给你一个整数数组 cost
,其中 cost[i]
是从楼梯第 i
个台阶向上爬需要支付的费用。一旦你支付此费用,即可选择向上爬一个或者两个台阶。
你可以选择从下标为 0
或下标为 1
的台阶开始爬楼梯。
请你计算并返回达到楼梯顶部的最低花费。
解法:动态规划的特点就是,从下向上推出答案,题目说第一次,可以从第0阶开始爬,也可以从第1阶开始爬,那就是分为了两种答案。
那我们按照动态规划的解题步骤来,我们开一个二维dp数组 dp[2][n]。
dp[0]记录 从第0层开始,直到第n层的最小花费,dp[0] [i] 表示从第0层开始,到达第i层的最小花费
dp[1]记录 从第1层开始,直到第n层的最小花费,dp[1] [i] 表示从第1层开始,到达第i层的最小花费
那我们可以发现,第i层,可能是由第i-2层跳上来的,或者第i-1层跳上来的,由于我们的dp数组状态表示的是 dp[x] [i] 表示从第x层开始,到达第i层的最小花费, 那么到达第i层的最小花费就是,min(dp[i-2]+cost[i-2] , dp[i-1]+cost[i-1]),把两种情况都计算一遍,
最后返回min(dp[0][n],dp[1][n])即可。
class Solution {
public:
int minCostClimbingStairs(vector<int>& cost) {
//dp[0][i] 表示 从第0阶开始到达第i阶的最小花费
//dp[1][i] 表示 从第1阶开始到达第i阶的最小花费
if(cost.size()<=2)return min(cost[0],cost[1]);
int dp[2][cost.size()+10];
dp[0][0]=dp[0][1]=dp[0][2]=cost[0];
dp[1][1]=dp[1][2]=dp[1][3]=cost[1];
for(int i=3;i<=cost.size();i++)
{
dp[0][i]=min(dp[0][i-2]+cost[i-2],dp[0][i-1]+cost[i-1]);
}
for(int i=4;i<=cost.size();i++)
{
dp[1][i]=min(dp[1][i-2]+cost[i-2],dp[1][i-1]+cost[i-1]);
}
return min(dp[0][cost.size()],dp[1][cost.size()]);
}
};
其实还可以继续优化成一维,我们把0下标和1下标初始化为0就可以了,因为只有要跳的时候才需要付出代价。
class Solution {
public:
int minCostClimbingStairs(vector<int>& cost) {
//dp[0][i] 表示 从第0阶开始到达第i阶的最小花费
//dp[1][i] 表示 从第1阶开始到达第i阶的最小花费
if(cost.size()<=2)return min(cost[0],cost[1]);
int dp[cost.size()+10];
dp[0]=dp[1]=0;
for(int i=2;i<=cost.size();i++)
{
dp[i]=min(dp[i-1]+cost[i-1],dp[i-2]+cost[i-2]);
}
return dp[cost.size()];
}
};