理论
背包问题
动规五步:
- 确定dp数组(dp table)以及下标的含义
- 确定递推公式
- dp数组如何初始化
- 确定遍历顺序
- 举例推导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]