如果一个问题具有以下两个要素:
• 最优子结构 (optimal substructure)
• 重叠子问题 (overlap subproblem)
• 描述最优解的结构。即抽象出一个状态来表示最优解。
• 递归的定义最优解的值。找出状态转移方程,然后递归的定义
• 计算最优解的值。典型的做法是自底向上,当然也可以自顶向下。
写代码实现时有两种方式,“递归 (recursive)+ 自顶向下 (top-down)+ 表格”和“自底向上
• 最优子结构 (optimal substructure)
• 重叠子问题 (overlap subproblem)
则可以用动态规划求最优解。
• 描述最优解的结构。即抽象出一个状态来表示最优解。
• 递归的定义最优解的值。找出状态转移方程,然后递归的定义
• 计算最优解的值。典型的做法是自底向上,当然也可以自顶向下。
• 根据计算过程中得到的信息,构造出最优解。
如果我们只需要最优解的值,不需要最优解本身,则可以忽略第 4 步。当执行第 4 步时,我们需要在第 3 步的过程中维护一些额外的信息,以便我们能方便的构造出最优解。
在第 1 步中,我们需要抽象出一个“状态”,在第 2 步中,我们要找出“状态转移方程”,然后才能递归的定义最优解的值。第 3 步和第 4 步就是写代码实现了。写代码实现时有两种方式,“递归 (recursive)+ 自顶向下 (top-down)+ 表格”和“自底向上
(boom-up)+ 表格”。前者属于一种 memorization (翻译为备忘录法),后者才是正宗的动规。
动规用表格将各个子问题的最优解存起来,避免重复计算,是一种空间换时间。
不同点:1、动规的子问题是重叠的,而贪心的子问题是不重叠的 (disjoint subproblems);2、动规不具有贪心选择性质;3、贪心的前进路线是一条线,而动规是一个 DAG。