「动态规划」如何求到达楼梯顶部的最低花费?

746. 使用最小花费爬楼梯icon-default.png?t=N7T8https://leetcode.cn/problems/min-cost-climbing-stairs/description/给你一个整数数组cost,其中cost[i]是从楼梯第i个台阶向上爬需要支付的费用。一旦你支付此费用,即可选择向上爬1个或者2个台阶。你可以选择从下标为0或下标为1的台阶开始爬楼梯。请你计算并返回到达楼梯顶部的最低花费。

  1. 输入:cost = [10,15,20],输出:15,解释:你将从下标为1的台阶开始。支付15,向上爬2个台阶,到达楼梯顶部。总花费为15。
  2. 输入:cost = [1,100,1,1,1,100,1,1,100,1],输出:6,解释:你将从下标为0的台阶开始。支付1,向上爬2个台阶,到达下标为2的台阶;支付1,向上爬2个台阶,到达下标为4的台阶;支付1,向上爬2个台阶,到达下标为6的台阶;支付1,向上爬1个台阶,到达下标为7的台阶;支付1,向上爬2个台阶,到达下标为9的台阶;支付1,向上爬1个台阶,到达楼梯顶部。总花费为6。

提示:2 <= cost.length <= 1000,0 <= cost[i] <= 999。


我们用动态规划的思想来解决这个问题。由于cost的下标范围是[0, n - 1],故到达楼梯顶部的最低花费等价于到达n位置的最低花费。

确定状态表示:根据经验和题目要求,我们用dp[i]表示到达i位置的最低花费

推导状态转移方程:到达i位置的最低花费和最近的一步有关。

  • 我们可以先到i - 1位置,支付cost[i - 1],再向上爬1个台阶。由于到i - 1位置的最低花费是dp[i - 1],这种情况总共的最低花费是dp[i - 1] + cost[i - 1]。
  • 我们也可以先到i - 2位置,支付cost[i - 2],再向上爬2个台阶。由于到i - 2位置的最低花费是dp[i - 2],这种情况总共的最低花费是dp[i - 2] + cost[i - 2]。

要求的是到达i位置的最低花费,即上面2种情况的较小值,也就是说dp[i] = min(dp[i - 1] + cost[i - 1], dp[i - 2] + cost[i - 2])

初始化:根据状态转移方程,计算dp[0]和dp[1]时会越界,所以需要初始化。由于可以选择从下标为0或1的位置开始向上爬,所以dp[0] = dp[1] = 0

填表顺序:根据状态转移方程,dp[i]依赖于dp[i - 1]和dp[i - 2],故应从左往右填表

返回值:到达楼梯顶部的最低花费等价于到达n位置的最低花费,故应返回dp[n]

细节问题:由于下标范围是[0, n],故dp表的规模是1 x (n + 1)

class Solution {
public:
    int minCostClimbingStairs(vector<int>& cost) {
        int n = cost.size();

        // 创建dp表
        vector<int> dp(n + 1);

        // 填表
        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];
    }
};
  • 11
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

努力学习游泳的鱼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值