
动态规划同样是一种将问题分解为求解子问题的方法,不过与分治不同的是,动态规划算法的子问题不是相互独立的,而是有公共的部分,即有重叠子问题,这个时候使用分治算法,将会重复计算公共的子问题,效率很低!而用某种方法将中间计算的结果保存下来,以供后面直接使用,将会大大提高效率,体现了一种“用空间换时间的”思想!

那么什么样的问题才可以使用动态规划方法呢?有两个条件:

动态规划算法的设计步骤:

接下来,将通过几个例子来体会动态规划的基本思想。
例1: 最长公共子序列问题

思考,该问题的优化子结构是:

证明如下:


递归的定义最优解的代价:

重叠子问题:

建立递归方程:

则从左往右、从上往下进行计算:

写出算法的伪代码如下:

构造最优解:


例2: 矩阵链乘法

注意到,矩阵链乘法的代价对于不同的计算顺序,代价也不同。

优化子结构:

重叠子问题:

递归的定义最优解的代价:


自底向上的计算最优解的代价:

算法的伪代码如下:

构造最优解:

算法的时间复杂度与空间复杂度分析:

例3: 0/1背包问题


思考 :
优化子结构:

重叠子问题:

建立递归方程:


自底向上的计算最优解的代价:

算法的伪代码如下:

构造优化解:

算法复杂度分析:

例4: 最优的二叉搜索树
先来看下二叉搜索树的相关概念:(可以参考:二叉搜索树)


问题的定义:

思考 :该问题怎么去划分子问题?是否具有优化子结构呢?

优化子结构:

建立递归方程:


所以:

自下而上的计算优化解的搜索代价:


算法伪代码如下:

其中:

算法的复杂度分析:

参考资源:
【1】哈工大骆吉洲《算法分析与设计》PPT