动态规划(Dynamic programming,DP)是一种在数学、计算机科学和经济学中使用的,通过把原问题分解为相对简单的子问题的方式求解复杂问题的方法。 动态规划常常适用于有重叠子问题和最优子结构性质的问题,动态规划方法所耗时间往往远少于朴素解法。动态规划背后的基本思想非常简单--大致上,若要解一个给定问题,我们需要解其不同部分(即子问题),再合并子问题的解以得出原问题的解。 通常许多子问题非常相似,为此动态规划法试图仅仅解决每个子问题一次,从而减少计算量: 一旦某个给定子问题的解已经算出,则将其记忆化存储,以便下次需要同一个子问题解之时直接查表。 这种做法在重复子问题的数目关于输入的规模呈指数增长时特别有用。
动态规划一般可分为线性动态规划,区域动态规划,树形动态规划,背包动态规划四类,典型的例子如:
线性动态规划:拦截导弹,合唱队形,挖地雷,建学校,剑客决斗等
区域动态规划:石子合并, 加分二叉树,统计单词个数,炮兵布阵等
树形动态规划:贪吃的九头龙,二分查找树,聚会的欢乐,数字三角形等
背包动态规划:01背包问题,完全背包问题,分组背包问题,二维背包,装箱问题,挤牛奶(同济ACM第1132题)等