Day 38 | 动态规划 01

56 阅读1分钟

理论

背包问题

动规五步:

  1. 确定dp数组(dp table)以及下标的含义
  2. 确定递推公式
  3. dp数组如何初始化
  4. 确定遍历顺序
  5. 举例推导dp数组

509. 斐波那契数

斐波那契数本身的公式就是递推公式:

F(0) = 0,F(1) = 1 F(n) = F(n - 1) + F(n - 2)

需要注意的是下标赋值和取值范围

def fib(self, n: int) -> int:
    if n == 0: return 0
    dp = [0] * (n+1)
    dp[1] = 1
    for i in range(2, n+1):
        dp[i] = dp[i-1] + dp[i-2]
    return dp[n]

70. 爬楼梯

看做另一种形式的斐波那契

dp[i-1] 即 最后再爬一步

dp[i-2] 即 最后再爬两步

def climbStairs(self, n: int) -> int:
    dp = [1] * (n+1)
    for i in range(2, n+1):
        # 爬两阶 等价于 先爬一阶 或 爬零阶
        # 爬三阶 等价于 先爬一阶 + 两步 加上 爬两阶 + 一步
        dp[i] = dp[i-1] + dp[i-2]
    return dp[n]

746. 使用最小花费爬楼梯

选择花费较小的楼梯爬

def minCostClimbingStairs(self, cost: List[int]) -> int:
    dp = cost
    dp.append(0)
    for i in range(2, len(dp)):
        dp[i] += min(dp[i-1], dp[i-2])
    return dp[-1]