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;
    }
};

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

类似的题

猜你喜欢

转载自blog.csdn.net/Eric_1993/article/details/118014507