使用最小花费爬楼梯
题目描述
给你一个整数数组 cost
,其中 cost[i]
是从楼梯第 i
个台阶向上爬需要支付的费用。一旦你支付此费用,即可选择向上爬一个或者两个台阶。
你可以选择从下标为 0
或下标为 1
的台阶开始爬楼梯。
请你计算并返回达到楼梯顶部的最低花费。
示例 1:
python
输入:cost = [10,15,20]
输出:15
解释:你将从下标为 1 的台阶开始。
- 支付 15 ,向上爬两个台阶,到达楼梯顶部。
总花费为 15 。
题目链接:https://leetcode.cn/problems/min-cost-climbing-stairs
文章讲解:https://programmercarl.com/0746.使用最小花费爬楼梯.html
思路
以示例一为例:
到达楼梯顶部可以由i = 1或者i=2台阶往上爬到。
两种情况下的花费分别是 到达i=1台阶的最小花费加上cost[1]、到达i=2台阶的最小化非加上cost[2]。
这两者都有可能,但是要求是最低花费,因此我们选择这两种情况下花费最少的。
假设爬到第i阶,最少花费是dp[i],dp[i]就是原问题,子问题包括:
c++
dp[i-1],dp[i-2],dp[i-3],...,dp[2],dp[1]
这种自下而上,由**最小子问题的解(初试状态)+ 父问题与子问题之间的关系 (状态转移方程)**不断向上循环,直到得到所求 问题的解。正式动态规划的体现
递归五部曲
1、确定dp数组以及下标的含义
爬到第 i
阶,最少花费是 dp[i]
2、确定递推公式
C++
dp[i] = min(dp[i -1] +cost[i - 1],dp[i - 2]+cost[i-2])
3、dp 数组如何初始化
看一下递归公式,dp[i] 由dp[i - 1],dp[i - 2]推出,那么只初始化dp[0]和dp[1]就够了。
题目描述中明确说了 “你可以选择从下标为 0 或下标为 1 的台阶开始爬楼梯。” 也就是说 到达 第 0 个台阶是不花费的,但从 第0 个台阶 往上跳的话,需要花费 cost[0]。所以初始化 dp[0] = 0; dp[1] = 0;
4、确定遍历顺序
从前向后
5、举例推导dp数组
代码实现
C++
class Solution {
public:
int minCostClimbingStairs(vector<int>& cost) {
vector<int> dp(cost.size() + 1);
dp[0] = 0, dp[1] = 0;
for (int i = 2; i < cost.size() + 1; i++) {
dp[i] = min(dp[i - 1] + cost[i - 1], dp[i - 2] + cost[i - 2]);
}
return dp.back();
}
};
优化空间复杂度
C++
class Solution {
public:
int minCostClimbingStairs(vector<int>& cost) {
int dp0 = 0;
int dp1 = 0;
for (int i = 2; i <= cost.size(); i++) {
int dpi = min(dp1 + cost[i - 1], dp0 + cost[i - 2]);
dp0 = dp1; // 记录一下前两位
dp1 = dpi;
}
return dp1;
}
};