动态规划的四个基本原则
动态规划的四个基本原则(也叫 DP 四要素 / 四个核心条件),是判断一个问题能不能用动态规划解决的标准。结合信奥竞赛的使用场景,下面用最实用的方式讲清楚:
一、最优化原理(最优子结构性质)
含义:一个问题的最优解,可以由它的子问题的最优解构造出来。
换句话说:大问题的最优答案,一定包含着小问题的最优答案。
- 正面例子:最长上升子序列(LIS)。以第 \(i\) 个数结尾的 LIS,一定是从前面某个 \(j < i\) 的最优 LIS 后面接一个 \(a_i\) 得到的。
- 反例:最长简单路径问题(图中不能重复走节点的最长路)。子路径最优拼起来不一定整体最优,因为可能重复经过节点,所以不能用 DP。
💡 竞赛中的判断:如果题目问"最大/最小/最多/最少/最优",大概率满足最优化原理,优先考虑 DP。
二、无后效性
含义:当前阶段的状态一旦确定,后续阶段的决策只和当前状态有关,和之前是怎么到达这个状态的过程无关。
换句话说:过去不影响未来,只通过当前状态传递。
- 正面例子:01 背包。
dp[i][j]只关心"前 i 个物品、容量 j"时的最大价值,不关心前面具体选了哪些物品凑出来的。 - 反例:旅行商问题(TSP)。如果你只记"当前在城市 i",不够,因为你还必须知道哪些城市已经去过了,否则会重复走。这就是有后效性,需要加状态(比如状压 DP)来消除后效性。
💡 竞赛中的判断:定义完 dp 状态后问自己——仅凭这个状态,我能算出后面的答案吗?如果不能,说明状态信息不够,要加维度。
三、子问题重叠性
含义:在求解过程中,同一个子问题会被反复多次计算。
换句话说:暴力递归时,有大量重复计算的子问题。
- 正面例子:斐波那契数列。
fib(5)要算fib(4)和fib(3),fib(4)又要算fib(3)……fib(3)被重复算了很多次。 - 这正是 DP 比暴力搜索快的根本原因:用记忆化 / 递推把每个子问题只算一次,存起来反复用。
💡 补充:如果所有子问题都不重复(比如二分查找),那就没必要用 DP,直接分治就好了。子问题重叠越多,DP 收益越大。
四、状态可定义性(可描述性)
含义:能够用有限的维度(数量不多的参数)把问题的状态清晰地描述出来。
换句话说:能用数组的下标把"当前局面"表示出来。
- 正面例子:背包问题——用"考虑到第几个物品 + 还剩多少容量"两个维度就能完整描述局面。
- 反例:围棋。局面太复杂,无法用几个参数描述清楚,不能直接用 DP。
💡 竞赛中的判断:状态维度 × 每维大小 = 总状态数。如果总状态数在 \(10^5 \sim 10^7\) 范围内,通常是可行的 DP;如果太大,就要优化状态或换方法。
📌 快速记忆口诀
| 原则 | 一句话总结 | 解决什么问题 |
|---|---|---|
| 最优子结构 | 大最优由小最优组成 | DP 能不能得到最优解? |
| 无后效性 | 过去只通过现在影响未来 | DP 状态定义对不对? |
| 子问题重叠 | 同一个子问题算很多次 | DP 比暴力快在哪? |
| 状态可定义 | 能用有限维度描述局面 | DP 能不能实现? |
💡 竞赛实战中怎么用?
拿到一道题,按这个四步自检:
- 问最优值吗? → 是,满足最优化原理,考虑 DP。
- 能定义出 dp 数组吗? → 能,状态可定义。
- 当前状态够不够推后面? → 够,无后效性。
- 子问题会不会重复算? → 会,重叠子问题,DP 有效率收益。
四个条件都满足 → 这道题可以用 DP 做。

浙公网安备 33010602011771号