4.使用最小花费爬楼梯

数组的每个索引做为一个阶梯,第 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。

注意:

  1. cost 的长度将会在 [2, 1000]
  2. 每一个 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]; 
    }
}

猜你喜欢

转载自blog.csdn.net/qq_40636117/article/details/81475680