题目描述
给你一个整数数组 cost,其中 cost[i] 是从楼梯第 i 个台阶向上爬需要支付的费用。一旦你支付此费用,即可选择向上爬一个 或两个台阶。
你可以选择从下标为 0 或下标为 1 的台阶开始爬楼梯。
请你计算并返回达到楼梯顶部(即越过最后一个台阶)的最低花费。
输入描述
一行,包含若干整数(用空格分隔),表示 cost 数组,长度范围为 2 <= cost.length <= 1000,每个元素 0 <= cost[i] <= 999。
输出描述
一个整数,表示达到楼梯顶部的最低花费。
示例
输入:
text
10 15 20
输出:
text
15
说明: 从下标 1 的台阶开始(花费 15),向上爬两个台阶到达顶部,总花费 15。
输入:
text
1 100 1 1 1 100 1 1 100 1
输出:
text
6
说明: 从下标 0 开始,依次走 0→2→3→4→6→7→9→顶部,花费 1+1+1+1+1+1 = 6。
输入:
text
0 0 1 0
输出:
text
0
C++ 解决方法(动态规划)
思路: 设 dp[i] 表示到达第 i 个台阶所需的最小花费。
-
起始状态:可以从第 0 或第 1 个台阶开始,所以
dp[0] = 0,dp[1] = 0(到达这两个台阶本身不花钱,只有从它们"往上爬"才花钱)。 -
状态转移:到达第
i个台阶,可以从第i-1个台阶爬上来(支付cost[i-1]),也可以从第i-2个台阶爬上来(支付cost[i-2]):text
dp[i] = min(dp[i-1] + cost[i-1], dp[i-2] + cost[i-2]) -
最终答案是
dp[n],其中n = cost.size(),表示越过最后一个台阶到达顶部。
由于 dp[i] 只依赖前两项,可以用滚动变量 把空间优化到 O(1)。
时间复杂度 O(n),空间复杂度 O(1)。
cpp
#include <iostream>
#include <sstream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
class Solution {
public:
int minCostClimbingStairs(vector<int>& cost) {
int n = cost.size();
// dp[i] 表示到达第 i 个台阶的最小花费
// 用滚动变量优化空间
int prev2 = 0; // dp[0]
int prev1 = 0; // dp[1]
for (int i = 2; i <= n; i++) {
int cur = min(prev1 + cost[i - 1], prev2 + cost[i - 2]);
prev2 = prev1;
prev1 = cur;
}
return prev1; // dp[n],即到达顶部的最小花费
}
};
int main() {
string line;
getline(cin, line);
vector<int> cost;
istringstream iss(line);
int x;
while (iss >> x) {
cost.push_back(x);
}
Solution sol;
cout << sol.minCostClimbingStairs(cost) << endl;
return 0;
}