1、题目描述
数组的每个下标作为一个阶梯,第 i 个阶梯对应着一个非负数的体力花费值 cost[i](下标从 0 开始)。
每当你爬上一个阶梯你都要花费对应的体力值,一旦支付了相应的体力值,你就可以选择向上爬一个阶梯或者爬两个阶梯。
请你找出达到楼层顶部的最低花费。在开始时,你可以选择从下标为 0 或 1 的元素作为初始阶梯。
2、算法分析
每当你爬上一个阶梯你都要花费对应的体力值,一旦支付了相应的体力值,你就可以选择向上爬一个阶梯或者爬两个阶梯。上一步影响着下一步的走向。动态规划!
①确定dp数组以及下标的含义。
dp[i]的定义:到达第i个台阶所花费的最少体力dp[i];
②确定递推公式
有两个途径得到dp[i],一个是dp[i-1] 一个是dp[i-2]。
那么究竟是选dp[i-1]还是dp[i-2]呢?
一定是选最小的,所以dp[i] = min(dp[i - 1], dp[i - 2]) + cost[i];
注意这里为什么是加cost[i],而不是cost[i-1],cost[i-2]之类的,因为题目中说了:每当你爬上一个阶梯你都要花费对应的体力值。
注意:解释下
dp[i] = min(dp[i-2], dp[i-1]) +cost[i],要想到达 i,要么交 i-2 的体力值走两步上来,要么交 i-1 的体力值走一步上来。
③初始化递推公式
那么看一下递归公式,dp[i]由dp[i-1],dp[i-2]推出,既然初始化所有的dp[i]是不可能的,那么只初始化dp[0]和dp[1]就够了,其他的最终都是dp[0]dp[1]推出。
dp[0] = cost[0]; dp[1] = cost[1];
④确定遍历顺序
其实就是顺序遍历。
3、代码实现
class Solution {
public int minCostClimbingStairs(int[] cost) {
if(cost == null || cost.length == 0){
return 0;
}
// 到达第i个台阶所花费的最少体力dp[i];
int[] dp = new int[cost.length];
// 初始化
dp[0] = cost[0];
dp[1] = cost[1];
//
for(int i = 2;i < cost.length;i++){
// 第i个台阶需要的体力值 cost[i]:每当你爬上一个阶梯你都要花费对应的体力值
dp[i] = Math.min(dp[i-1],dp[i-2]) + cost[i];
}
// 求的是最小体力值
return Math.min(dp[cost.length-1],dp[cost.length - 2]);
}
}