爬楼梯的最少成本

问题分析

这是一个典型的动态规划问题,目标是找到爬上楼梯的最低体力消耗。可以从第 0 或第 1 个阶梯开始,每次可以选择爬 1 或 2 个阶梯,最终需要到达数组末尾之后的位置(即楼顶)。

动态规划解法

动态规划的核心是定义状态和状态转移方程。设 dp[i] 表示到达第 i 个阶梯时的最低体力消耗。

状态转移方程

对于第 i 个阶梯,可以从 i-1i-2 阶梯到达:

  • 如果从 i-1 到达,则消耗为 dp[i-1] + cost[i-1]
  • 如果从 i-2 到达,则消耗为 dp[i-2] + cost[i-2]

因此,状态转移方程为: [ dp[i] = \min(dp[i-1] + cost[i-1], dp[i-2] + cost[i-2]) ]

初始条件
  • dp[0] = 0:初始位置可以是第 0 个阶梯,且不需要消耗体力;
  • dp[1] = 0:初始位置也可以是第 1 个阶梯,同样不需要消耗体力。
目标

最终目标是计算 dp[n],其中 n 是数组 cost 的长度。因为楼顶是第 n 个阶梯之后的位置。

代码实现

def minCostClimbingStairs(cost):
    n = len(cost)
    dp = [0] * (n + 1)
    for i in range(2, n + 1):
        dp[i] = min(dp[i-1] + cost[i-1], dp[i-2] + cost[i-2])
    return dp[n]

示例测试
cost = [10, 15, 20]
print(minCostClimbingStairs(cost))  # 输出:15

解释:

  • 从第 1 个阶梯开始(消耗 0),支付 15 后爬 2 步到达楼顶,总消耗为 15。

空间优化

由于 dp[i] 只依赖于 dp[i-1]dp[i-2],可以用两个变量代替数组,将空间复杂度优化到 O(1)。

优化后的代码
def minCostClimbingStairs(cost):
    prev1, prev2 = 0, 0
    for i in range(2, len(cost) + 1):
        current = min(prev1 + cost[i-1], prev2 + cost[i-2])
        prev2, prev1 = prev1, current
    return prev1

复杂度分析

  • 时间复杂度:O(n),需要遍历数组一次;
  • 空间复杂度:O(1),仅使用常数空间。

边界情况

  • 如果 cost 为空,直接返回 0;
  • 如果 cost 长度为 1,可以从第 0 或第 1 个阶梯开始,直接到达楼顶,因此返回 0。

完整代码示例

def minCostClimbingStairs(cost):
    if not cost:
        return 0
    prev1, prev2 = 0, 0
    for i in range(2, len(cost) + 1):
        current = min(prev1 + cost[i-1], prev2 + cost[i-2])
        prev2, prev1 = prev1, current
    return prev1

# 测试
print(minCostClimbingStairs([10, 15, 20]))  # 15
print(minCostClimbingStairs([1, 100, 1, 1, 1, 100, 1, 1, 100, 1]))  # 6

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值