给你一个整数数组
cost
,其中cost[i]
是从楼梯第i
个台阶向上爬需要支付的费用。一旦你支付此费用,即可选择向上爬一个或者两个台阶。你可以选择从下标为
0
或下标为1
的台阶开始爬楼梯。请你计算并返回达到楼梯顶部的最低花费。
示例 1:
输入:cost = [10,15,20] 输出:15 解释:你将从下标为 1 的台阶开始。 - 支付 15 ,向上爬两个台阶,到达楼梯顶部。 总花费为 15 。
- 1
- 2
- 3
- 4
- 5
示例 2:
输入:cost = [1,100,1,1,1,100,1,1,100,1] 输出:6 解释:你将从下标为 0 的台阶开始。 - 支付 1 ,向上爬两个台阶,到达下标为 2 的台阶。 - 支付 1 ,向上爬两个台阶,到达下标为 4 的台阶。 - 支付 1 ,向上爬两个台阶,到达下标为 6 的台阶。 - 支付 1 ,向上爬一个台阶,到达下标为 7 的台阶。 - 支付 1 ,向上爬两个台阶,到达下标为 9 的台阶。 - 支付 1 ,向上爬一个台阶,到达楼梯顶部。 总花费为 6 。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
提示:
2 <= cost.length <= 1000
0 <= cost[i] <= 999
i
位置为结尾dp[i]
表示到达i
位置时的最小花费(注意:到达i
位置的时候,i
位置的钱不需要算上)
根据最近的一步,分情况讨论:
先到达i-1
的位置,然后支付cost[i-1]
,接下来走一步到i
位置:dp[i-1]+cost[i-1]
先到达i-2
的位置,然后支付cost[i-2]
,接下来走两步到i
位置:dp[i-2]+cost[i-2]
从我们的递推公式可以看出,我们需要先初始化i=0
,以及i=1
的位置的值。容易得到dp[0]=dp[1]=0
,因为不需要任何花费,就可以直接站到0
层和第1
层上
填表顺序:
根据状态转移方程可得,遍历的顺序是从左往右
返回值
根据状态表示以及题目要求,需要返回dp[n]
位置的值
class Solution {
public:
int minCostClimbingStairs(vector& cost) {
int n=cost.size();
//创建一个pd表
vectordp(n+1,0);
//初始化
dp[0]=dp[1]=0;
//填表
for(int i=2;i
以i
位置为起点
dp[i]
表示:从i
位置出发,到达楼顶,此时的最小花费
根据最近的一步,分情况讨论:
支付cost[i]
,往后走一步,接下来从i+1
的位置出发到终点:dp[i+1]+cost[i]
支付cost[i]
,往后走两步,接下来从i+2
的位置出发到终点:dp[i+2]+cost[i]
我们要的是最小花费,因此dp[i]=min(dp[i+1],dp[i+2])+cost[i]
为了保证填表的时候不越界,我们需要初始化最后两个位置,结合状态表示易得:dp[n-1]=cost[n-1]
,dp[n-2]=cost[n-2]
根据状态转移方程可得,遍历的顺序是从左往右
dp[n]
位置的值class Solution {
public:
int minCostClimbingStairs(vector& cost) {
int n=cost.size();
//创建dp表
vectordp(n);
//初始化
dp[n-1]=cost[n-1],dp[n-2]=cost[n-2];
//填表顺序
for(int i=n-3;i>=0;i--)
{
dp[i]=min(dp[i+1],dp[i+2])+cost[i];
}
//返回值
return min(dp[0],dp[1]);
}
};