动态规划适合具有重叠子问题和最优子结构的问题。它把递归搜索中的重复状态保存下来,使每个状态只求一次。关键不在背公式,而在定义 dp 的含义:它必须足以描述后续决策所需的信息。

标准步骤是:确定状态;列出选择;写转移方程;设置边界;决定遍历顺序;判断是否能压缩空间。以台阶计数为例,若每次走一或两级,dp[i] 表示到达第 i 级的方法数,则最后一步来自 i-1i-2,所以 dp[i]=dp[i-1]+dp[i-2]

背包问题尤其依赖顺序。0/1 背包中每件物品只能使用一次,一维数组的容量必须倒序遍历,避免当前物品被重复读取;完全背包允许重复使用,容量通常正序。子序列问题常把 dp[i]dp[i][j] 定义为以某位置结尾或两个前缀上的答案。

若有 S 个状态、每个状态枚举 T 个选择,时间通常为 O(ST),空间为状态表大小。记忆化搜索与自底向上 DP 在渐近复杂度上常相同:前者接近自然递归且只访问可达状态,后者无栈开销且遍历可控。

误区包括状态含义含糊、初始化与定义冲突、只写方程不说明遍历依赖、盲目空间压缩覆盖尚未使用的值,以及把所有最优化问题都套 DP。小结:先用一句完整中文定义状态,再从“最后一步发生什么”推导转移,正确性会比背模板可靠。