引言
动态规划是解决具有重叠子问题和最优子结构性质问题的一种算法设计技术。它将复杂问题分解为更小的子问题,通过保存子问题的解来避免重复计算,从而提高算法效率。动态规划广泛应用于最优化问题,如资源分配、路径规划、序列比对等领域。
动态规划基本概念
核心要素
动态规划问题通常具有以下三个核心要素:
- 重叠子问题:问题可以分解为相互重叠的子问题
- 最优子结构:问题的最优解包含子问题的最优解
- 无后效性:某阶段状态一旦确定,不受这个状态以后决策的影响
解题步骤
使用动态规划解决问题通常包括以下步骤:
- 定义状态:确定用哪些变量表示问题的状态
- 状态转移方程:找出状态之间的递推关系
- 初始化:确定初始状态的值
- 计算顺序:确定状态的计算顺序
- 返回结果:根据计算结果返回最终答案
经典动态规划问题
0-1 背包问题
0-1 背包问题是动态规划的经典问题之一。给定一个容量为 cap 的背包和 n 个物品,每个物品有重量 wgt[i] 和价值 val[i],要求在不超过背包容量的前提下,使装入背包的物品总价值最大。
暴力搜索解法
def knapsack_dfs(wgt: list[int], val: list[int], i: int, c: int) -> int:
"""0-1 背包:暴力搜索"""
# 若已选完所有物品或背包无剩余容量,则返回价值 0
if i == 0 or c == 0:
return 0
# 若超过背包容量,则只能选择不放入背包
if wgt[i - 1] > c:
return knapsack_dfs(wgt, val, i - 1, c)
# 计算不放入和放入物品 i 的最大价值
no = knapsack_dfs(wgt, val, i - 1, c)
yes = knapsack_dfs(wgt, val, i - 1, c - wgt[i - 1]) + val[i - 1]
(no, yes)

