746. Min Cost Climbing Stairs* (使用最小花费爬楼梯)

746. Min Cost Climbing Stairs* (使用最小花费爬楼梯)

https://leetcode.com/problems/min-cost-climbing-stairs/

题目描述

You are given an integer array cost where cost[i] is the cost of ith step on a staircase. Once you pay the cost, you can either climb one or two steps.

You can either start from the step with index 0, or the step with index 1.

Return the minimum cost to reach the top of the floor.

Example 1:

Input: cost = [10,15,20]
Output: 15
Explanation: Cheapest is: start on cost[1], pay that cost, and go to the top.

Example 2:

Input: cost = [1,100,1,1,1,100,1,1,100,1]
Output: 6
Explanation: Cheapest is: start on cost[0], and only step on 1s, skipping cost[3].

Constraints:

  • 2 <= cost.length <= 1000
  • 0 <= cost[i] <= 999

代码实现

我觉得这道题有意思的地方在于, 每次去写它总认为自己会写错. 今天才明白, 之所以会产生这样的想法, 是因为我之前并没有将求解方法纳入现有的思考体系中. 之前在 746. Min Cost Climbing Stairs* 写的状态方程虽然简洁, 但感觉不符合我现在的思考方式.

本题采用动态规划求解, 使用 dp[i] 表示达到 i 时所需要付出的最小代价. 假设 cost 数组的大小为 N, 最终的目标就是跳到第 N 个位置上, 所付出的代价就是 dp[N]. 根据题意, 当你位于第 i 个位置时, 付出当前位置的花费 cost[i], 就可以跳一步或者两步. 那么要跳到第 i 个位置上时, 要么一开始就位于第 i - 1 的位置上, 然后付出 cost[i - 1] 的代价跳一步到达第 i 个位置; 要么一开始位于第 i - 2 的位置上, 然后付出 cost[i - 2] 的代价跳两步到达第 i 个位置;
综上, 状态转移方程呼之欲出:

dp[i] = min(dp[i - 1] + cost[i - 1], dp[i - 2] + cost[i - 2])

要确定初始状态, 题目中说可以从第 0 个位置和第 1 个位置开始起跳, 那么:

dp[0] = 0;
dp[1] = 0;

再次注意 dp[i] 的含义是到达 i 时所需要付出的最小代价, 该位置上的花费 cost[i] 指的是你要离开 第 i 个位置时需要付出的代价, 由于我们可以直接从第 0 个位置和第 1 个位置开始起跳, 所以它们的初始值均设置为 0. 最后我们只需要返回 dp[N] 就可以求解, 代码如下:

class Solution {
public:
    int minCostClimbingStairs(vector<int>& cost) {
        int N = cost.size();
        vector<int> dp(N + 1, 0);
        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];
    }
};

注意题目中说了数组的大小至少为 2, 所以 N < 2 的情况不用考虑. 写到这, 代码还不算完, 还需要考虑能否进一步优化. 观察到 dp[i] 的结果只和 dp[i - 1]dp[i - 2] 有关, 似乎不需要使用 vector 来记录所有历史结果, 只需要使用变量 dp0 = dp[i - 2], dp1 = dp[i - 1] 来保留历史状态, 同时不断维护 dp0dp1 的状态.

class Solution {
public:
    int minCostClimbingStairs(vector<int>& cost) {
        int N = cost.size();
        int dp0 = 0, dp1 = 0, dp2 = 0;
        for (int i = 2; i <= N; ++ i) {
            dp2 = min(dp1 + cost[i - 1], dp0 + cost[i - 2]);
            dp0 = dp1;
            dp1 = dp2;
        }
        return dp2;
    }
};

另外可以看看下面 “类似的题”, 均采用相同的思路就可以求解.

类似的题

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值