剑指 Offer II 088. 爬楼梯的最少成本 - 力扣(LeetCode)
可以从第0或者第1作为起始台阶、每次可以选择跳1或2步、到楼顶结束
tips: 经验+题目要求。以i位置为结尾,。。。
dp[i] : 到达i位置时,最小花费
tips: 用之前或之后的状态,推导出dp[i]的值。根据最近的一步,来划分问题
到达i位置之前:
由于状态表示以及定义,需要选择到达i位置的最小花费
即:dp[i] = min(dp[i-1] + cost[i-1], dp[i-2] + cost[i-2])
tips: 保证填表的时候不越界。i为0时,需要dp[-1]和dp[-2]会越界
题目要求:可以从0或者1下标作为初始台阶
dp[0] = dp[1] = 0
由前面的dp[i - 1],dp[i - 2]值可以推导dp[i]
从左往右(---->)
楼顶在n下标处
return dp[n]
代码
class Solution {
public:
int minCostClimbingStairs(vector& cost) {
//1.创建dp表
//2.初始化
//3.填表
//4.返回值
int n = cost.size();
vector dp(n + 1, 0);
for(int i = 2; i <= n; ++i)
dp[i] = min(dp[i - 1] + cost[i - 1], dp[i - 2] + cost[i - 2]);
return dp[n];
}
};
以i位置为起点,。。。
dp[i] : 从i位置出发,到达楼顶,此时的最小发费
到达i位置之后:
由于状态表示以及定义,需要从那个位置开始(i+1、i+2)到终点的花费最小
即:dp[i] = min(dp[i + 1], dp[i + 2]) + cost[i]
tips: 保证填表的时候不越界。
从楼顶(n下标)到楼顶的花费为0
dp[n - 1] = cost[n - 1], dp[n - 2] = cost[n - 2]
由前面的dp[i + 1],dp[i + 2]值可以推导dp[i]
从右往左(<----)
根据状态定义,题目要求
return min(dp[0], dp[1])
代码
class Solution {
public:
int minCostClimbingStairs(vector& cost) {
//1.创建dp表
//2.初始化
//3.填表
//4.返回值
int n = cost.size();
vector dp(n, 0);
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]);
}
};
首先根据题目要求和经验(一般经验:以某个位置为结尾或以某个位置为起点,。。。)推导出状态表示。
根据状态表示来推状态转移方程。如果定义的状态表示不能够推导出状态转移方程,则状态表示是错误的。
新手要敢于自己定义状态表示,孰能生巧,大量做题后,状态表示的定义往往会向着正确的方向。
观看~~