初步了解动态规划
动态规划是一种数学规划方法,用于解决具有overlapping subproblems 和 optimal substructure属性的问题,能比天真的算法节省很多时间。
首先讲一下什么是overlapping subproblems。它是指可以被分解成若干次重用的子问题的那类问题。例如Fibonacci sequence(斐波纳契数列,每个数等于前两个数的和,其中fib(0) = 1且fib(1) = 1)。对于overlapping subproblems,天真的算法可能重复计算某些子问题,浪费时间。而dynamic programming使用memoization来解决这个问题,即把计算的结果保存起来,需要的时候取出使用即可。
那么什么是optimal substructure呢?如果可以从其子问题的最优解构造出该问题的最优解,则该问题具有optimal substructure属性。据有optimal substructure的问题适合用动态规划和贪心算法求解。例子是寻找一个图中两个顶点间的最短路径,先找到从开始点的所有邻居到目标的最短路径(递归地使用这一过程),然后选择整体的最短路径。
通常我们可以用三个步骤对具有optimal substructure属性的问题求解:
- 把问题分解成subproblems。
- 递归地使用这三个步骤求出这些问题的最优解。
- 使用局部最优解构造整体最优解。
综上,dynamic programming使用了三种技术:overlapping subproblems, optimal substructure and memoization.
动态规划通常采取两种方法: top-down approach(合并了recursion和memoization)和bottom-up approach(性能稍好,但很难直观地列出所有子问题).
dynamic programming是由Richard Bellman在1940s提出的。bellman的主要贡献是Bellman equation,aka, dynamic programming equation.是dynamic programming最优性的必要条件。
附:贪心算法
贪心算法的特点:每一阶段都追求局部最优,希望最终达到全局最优。
贪心算法能对具有两种属性的问题工作的很好:greedy choice property和optimal substructure.
optimal substructure在上面已经介绍过,greedy choice property是指在做每一步的选择时不需要和以前的选择一起考虑。
贪心算法不会回溯以前的选择,这是和动态规划的主要不同。