746.使用最小花费爬楼梯

  • 746.使用最小花费爬楼梯

  • 题目:
    数组cost的每个元素cost[ i ] 表示在 i 台阶处需花费cost [ i ] 体力值才能向上走;
    每次花费了体力可以选择向上走一或两步;
    初始位置为下标为0或1处;
    求最少花费多少体力值可以到达楼顶(楼顶指cost.size( ) 处)

  • 思路:
    1.DP:O(n), O(n)
    ①dp数组下标及定义:dp[ i ] 表示在爬完第 i 阶台阶所花费的最小值;
    ②递推公式:dp[ i ] = min ( dp [ i - 1 ] , dp [ i - 2 ] ) + cost [ i ] ;
    ③dp数组的初始化:初始位置可以从下标为0或1处开始,因此dp[ 0 ] = cost [ 0 ] , dp [ 1 ] = cost [ 1 ] ;
    ④确定遍历顺序:i 位置的值由 i - 1和 i - 2 决定,因此自然是从前往后遍历;
    ⑤举例推导dp数组:例如cost = [1, 100, 1, 1, 1, 100, 1, 1, 100, 1] ,则dp = [1,100, 2,3,3,103,4,5,104,6 ];最终可由104或6处登上楼顶,因此花费的最小体力值为min(104, 6) ;

class Solution {
public:
    int minCostClimbingStairs(vector<int>& cost) {
        int n = cost.size();
        if (n == 2) return min(cost[0], cost[1]);
    
        vector<int> dp(n);
        dp[0] = cost[0], dp[1] = cost[1];//初始化为0或1位置;
        for (int i = 2; i < n; ++i) {//dp[i]表示爬完第i个台阶需花费的最少体力;
            //第i个台阶可能由i-1或i-2而来,且每爬上一个台阶都要花费对应的体力值才能继续往前走;
            dp[i] = min(dp[i - 1], dp[i - 2]) + cost[i];
        }
        return min(dp[n- 1], dp[n - 2]);//楼顶可能由n-1或n-2到达;
    }
};

2.可以对1的空间进行优化;DP:O(n), O(1)

class Solution {
public:
    int minCostClimbingStairs(vector<int>& cost) {
        int n = cost.size();
        if (n == 2) return min(cost[0], cost[1]);
    
        int dp0 = cost[0], dp1 = cost[1];//相当于第一步要花费,最后一步从dp[n-1]或dp[n-2]到达楼顶   
        for (int i = 2; i < n; ++i) {           
            int temp = min(dp0, dp1) + cost[i];
            dp0 = dp1;
            dp1 = temp;
        }
        return min(dp0, dp1);
    }
};

3.与1,2思路不同的DP

class Solution {
public:
    int minCostClimbingStairs(vector<int>& cost) {
        int n = cost.size();
        if (n == 2) return min(cost[0], cost[1]);
    
        int dp0 = 0, dp1 = 0;//相当于第一步不用花费,最后一步要花费(从n-1花费cost[n-1]或从n-2花费cost[n-2]到达楼顶n)      
        for (int i = 2; i < n; ++i) {           
            int temp = min(dp0 + cost[i - 2], dp1 + cost[i - 1]);
            dp0 = dp1;
            dp1 = temp;
        }
        return min(dp0 + cost[n - 2], dp1+ cost[n - 1]);
    }
};
  • 总结:
    1,2是一种,3是一种,区别在于:1,2的dp[ i ] 已经算上了cost [ i ] ,因此每次算dp[ i ] 时,认为是从dp [ i - 1 ] 或dp [ i - 2 ] 上来的,再加上 i 阶的体力值cost [ i ] ;而3的dp[ i ] 没算当前这阶cost [ i ] ;但根据题目的例子:
    在这里插入图片描述
    起始位置是i = 1,花费cost[ 1 ] = 15,走两步到达楼顶,可以理解为第一步是要花费体力的,即每一步计算上当前的cost [ i ] 更好,即dp [ i ] 理解为爬完第 i 阶台阶的最少体力;
    下面贴一张解释图:
    在这里插入图片描述
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值