动态规划

概述

动态规划(Dynamic Programming, DP)是一种通过记忆化(memoization)或自底向上填表来避免重复计算的算法设计策略。其核心在于问题必须具备最优子结构重叠子问题两个要素。与贪心算法不同,动态规划会考虑所有可能的选择而非仅选局部最优;与分治法不同,动态规划的子问题是重叠的

定义

动态规划(Dynamic Programming)

动态规划是一种将复杂问题分解为若干重叠子问题,通过存储子问题的解来避免重复计算的算法策略。动态规划的两个核心要素:

  1. 最优子结构(Optimal Substructure):问题的最优解包含其子问题的最优解
  2. 重叠子问题(Overlapping Subproblems):递归求解时,相同的子问题会被反复计算

动态规划的两种实现方式:

  • 自顶向下(记忆化搜索):递归 + 缓存已计算的子问题解
  • 自底向上(填表法):按子问题规模从小到大依次求解,填入表格

核心性质

性质描述备注
最优子结构最优解包含子问题的最优解与贪心算法共享此性质
重叠子问题递归过程中子问题被反复计算这是使用 DP 的动机
记忆化/填表存储子问题解以避免重复计算将指数级复杂度降为多项式级
无后效性某阶段的状态一旦确定,后续决策不影响之前的状态DP 适用性的关键条件
考虑所有选择枚举所有可能的决策,而非只选局部最优区别于贪心算法

应用场景

动态规划在算法导论中的经典应用:

  • 最长公共子序列(LCS) 时间和空间,用于文本比较、DNA 序列比对
  • 矩阵链乘法 时间,找到最优括号化方案
  • 最优二叉搜索树 时间,构造平均搜索代价最小的 BST
  • 0-1 背包问题 时间,贪心算法无法解决
  • Fibonacci 数列:朴素递归 → DP 优化至
  • 编辑距离 时间,用于拼写检查、字符串匹配

动态规划 vs 贪心 vs 分治

比较维度动态规划贪心算法分治法
子问题重叠重叠通常不重叠不重叠
决策方式考虑所有选择选局部最优递归分解
最优性保证通常保证全局最优不一定取决于问题
存储需求需要表格通常不需要通常不需要
典型应用LCS、背包Dijkstra、Huffman归并排序、Strassen

参见