1.3 斐波那契数列模型:LeetCode 746. 使用最小花费爬楼梯


动态规划解最小花费爬楼梯问题:LeetCode 746. 使用最小花费爬楼梯


1. 题目链接

LeetCode 746. 使用最小花费爬楼梯
题目要求:给定一个整数数组 cost,其中 cost[i] 是从楼梯第 i 阶向上爬所需支付的费用。你可以从下标 01 的台阶开始爬,每次爬1或2阶,计算达到楼梯顶部(数组末尾之后)的最小花费。


2. 题目描述
  • 输入:整数数组 cost,例如 [10, 15, 20]
  • 输出:最小花费,例如 15(从下标1开始,直接走两步到达顶部)。
  • 约束条件
    • 2 ≤ cost.length ≤ 1000
    • 0 ≤ cost[i] ≤ 999

3. 示例分析

示例 1
输入:cost = [10, 15, 20]
输出:15
解释

  • 从下标1开始,支付15,走两步直接到达顶部,总花费为15。

示例 2
输入:cost = [1, 100, 1, 1, 1, 100, 1, 1, 100, 1]
输出:6
解释

  • 路径为 0→2→4→6→7→9→顶部,总花费为 1+1+1+1+1+1=6

4. 算法思路
动态规划递推
  1. 状态定义

    • dp[i] 表示到达第 i 阶的最小累计花费。
    • 注意:顶部位于第 n 阶(n = cost.size()),因此需要计算 dp[n]
  2. 状态转移方程

    • 到达第 i 阶的最小花费由前两阶的花费决定:
      dp[i] = min(dp[i-1] + cost[i-1], dp[i-2] + cost[i-2])
    • 解释:可以从第 i-1 阶走1步,或从第 i-2 阶走2步到达第 i 阶。
  3. 初始条件

    • dp[0] = 0(从起点开始,无需站在下标0的台阶)。
    • dp[1] = 0(从起点开始,直接选择下标1的台阶,无需支付下标1的费用)。

5. 边界条件与注意事项
  1. 边界处理

    • cost 数组长度为 1 时,直接返回 0(无需支付任何费用即可到达顶部)。
    • 当长度为 2 时,返回 min(cost[0], cost[1])
  2. 时间复杂度O(n),只需遍历一次数组。

  3. 空间优化:可进一步优化为滚动变量,将空间复杂度从 O(n) 降至 O(1)


6. 代码实现与解析
class Solution {
public:
    int minCostClimbingStairs(vector<int>& cost) {
        int n = cost.size();
        if (n == 0) return 0;    // 处理空数组(题目约束n≥2,实际无需)
        if (n == 1) return 0;     // 关键修正:避免越界
        
        vector<int> dp(n + 1, 0); // dp[i]表示到达第i阶的最小花费
        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];
    }
};
代码解析
  1. 初始化处理
    • 直接处理 n=0n=1 的情况,避免越界错误。
  2. 动态规划数组
    • dp[0]dp[1] 初始化为 0,因为从起点可以选择直接站在下标0或1的位置。
  3. 递推计算
    • i=2 开始,计算到达每阶的最小花费,确保每次取最小值。
  4. 返回值
    • dp[n] 表示到达顶部(第 n 阶之后)的最小花费。

总结

通过动态规划递推能够高效解决最小花费爬楼梯问题。关键点在于正确处理边界条件(如 n=1)和状态转移逻辑。此方法可扩展至类似路径选择问题,如带权重的跳跃游戏等。

你可能感兴趣的:(#,1.2,leecode动态规划习题,leetcode,算法,动态规划)