数组的每个索引做为一个阶梯,第 i
个阶梯对应着一个非负数的体力花费值 cost[i]
(索引从0开始)。
每当你爬上一个阶梯你都要花费对应的体力花费值,然后你可以选择继续爬一个阶梯或者爬两个阶梯。
您需要找到达到楼层顶部的最低花费。在开始时,你可以选择从索引为 0 或 1 的元素作为初始阶梯。
示例 1:
输入: cost = [10, 15, 20] 输出: 15 解释: 最低花费是从cost[1]开始,然后走两步即可到阶梯顶,一共花费15。
示例 2:
输入: cost = [1, 100, 1, 1, 1, 100, 1, 1, 100, 1] 输出: 6 解释: 最低花费方式是从cost[0]开始,逐个经过那些1,跳过cost[3],一共花费6。
注意:
cost
的长度将会在[2, 1000]
。- 每一个
cost[i]
将会是一个Integer类型,范围为[0, 999]
。
思路:
第一次分析的时候分析出错了,以[1, 100, 1, 1, 1, 100, 1, 1, 100, 1]为例,第一次我是资源分析的:
一个台阶:1
两个台阶:1,100
三个台阶:1,100,1
。
。
。
这样分析不对的原因是,题目的最终目的是要到达楼顶,而这样分析会让人不自觉地认为最后一个台阶是楼顶,从而发生了错误
所以在分析的时候要加上楼顶,既然到达楼顶就是最终目的,那不妨设楼顶的花费为0,像下面一样分析:
零个台阶:0
一个台阶:1,0
两个台阶:1,100,0
三个台阶:1,100,1,0
。。。
所以dp[0]=0;
由于一次可以迈两步,可以直接从越过一个台阶直接到楼顶,dp[1]也等于0
下面是分析一个台阶以上的情况。设i是某阶台阶(包括楼顶)
四个台阶: 1,100,1,1,0
由于一次最多迈两步,我可以从第四个台阶迈到楼顶,也可以从第三个迈过去
对于第四,第三个台阶的花费是确定的,分别为 cost[3] 与 cost [2],
第四,第三个台阶之前的最小花费分别是dp[3]与dp[2]
(别忘了dp[0]是零个台阶的花费,所以第四个台阶之前的最小花费应该是dp[3])
所以对于到楼顶,有如下两种选择:
到达倒数第一个台阶最小花费+本身花费,即cost[3]+dp[3]+0;
到达倒数第二个台阶最小花费+本身花费,即cost[2]+dp[2]+0
选择其中最小的一个
推而广之,到达第n(n>2)个台阶最小花费dp[n]=min(dp[n-2]+cost[n-2],dp[n-1]+cost[n-1]);
还有就是要注意dp与cost的对应关系
我之前还犯了个错误,dp[n]=min(dp[n-2]+cost[n-2],dp[n-1]+cost[n-1])+cost[n];
因为我将数组dp和cost对应错了。要是回过去看
零个台阶:0
一个台阶:1,0
两个台阶:1,100,0
三个台阶:1,100,1,0
这样的错误是不会犯的
代码
class Solution {
public int minCostClimbingStairs(int[] cost) {
int dp[]=new int[cost.length+1];
dp[0]=0;dp[1]=0;
for(int n=2;n<cost.length+1;++n){
dp[n]=Math.min(dp[n-1]+cost[n-1],dp[n-2]+cost[n-2]);
}
/*for(int a:dp){
System.out.printf("%d ",a);
}*/
return dp[cost.length];
}
}