“记忆化以需求驱动方式解状态,表格法则按依赖顺序主动求值。动态规划可用于 DAG 最短路、序列比对、背包、矩阵链乘、区间问题、树分解、概率模型与有限时域控制。其中计数、概率与可达性例子也说明,…”
形式陈述 ​
记忆化把递归函数对参数状态
直觉
递归树中许多分支会反复询问同一个子问题;记忆化把已经求出的输入—输出对缓存起来,将递归树折叠成状态 DAG,使同一状态再次出现时直接复用、每个节点只真正求值一次。它保留自顶向下、按需展开的控制流,只计算从初始问题可达的状态;代价是递归开销、哈希或数组查表和缓存空间。正确性依赖函数在同一状态上结果稳定,若状态遗漏了影响结果的环境,缓存会复用错误答案。
例子与边界
朴素 Fibonacci 递归重复计算
朴素 Fibonacci 递归重复计算
含环递归可能在结果写入缓存前再次访问同一状态,导致无限递归;需三色标记、固定点迭代或改成图算法。缓存无界增长也可能比重算更昂贵,工程中常配合淘汰策略,但淘汰不应改变纯函数正确性。
推论与应用
记忆化广泛用于解析、图搜索、游戏求值和最优化递推,也是把清晰递归定义转化为高效实现的直接技术。
它是 动态规划 的自顶向下实现,函数 的输入构成状态键。与表格法相比,记忆化适合稀疏可达状态和复杂转移;解析、博弈搜索、递归下降与 DAG 计算都可通过缓存把重叠子问题降为一次求值。
Memoization 只保证每个实际到达状态计算一次;若状态空间本身为全部子集,便得到子集 DP的指数上界,而非自动多项式。树宽 DP在树分解 bag 上缓存边界赋值,复杂度指数集中在宽度。自顶向下是否访问更少状态取决于实例可达性,最坏仍需与完整状态 DAG 比较,不能把“有缓存”当复杂度证明。
参考资料
- Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest, and Clifford Stein, Introduction to Algorithms, 4th ed., MIT Press, 2022,Parts I–VI。
- Jon Kleinberg and Éva Tardos, Algorithm Design, Pearson, 2005,Chs. 1–13。