第四部分 高级设计和分析技术
1. 动态规则通常用来解决最优化问题
2. 贪心算法通常用于最优化问题,其思想是每步选择都追求局部最优。其速度比动态规划方法快得多,但是,我们并不总能简单地判断出贪心算法是否有效
3. 摊还分析并不是通过分别分析每个操作的实际代价的界来分析操作序列的代价的界,而是直接分析序列整体的实际代价的界,好处是,虽然某些操作的代价可能很高,但其他很多操作的代价可能很价
第15章 动态规划
分治方法将问题划分为互不相交的子问题,递归地求解子问题,再将它们的解组合起来,求出原问题的解。
动态规划应用于子问题重叠的情况,即不同的子问题具有公共的子问题。也就是不同的子问题会涉及相同的子子问题。这样,普通的递归方法会反复的求解那些公共子问题,因而浪费了时间,动态规划则是对公共子问题只求解一次,然后将其解保存在表格中,避免了不必要的重复工作
按如下4个步骤来设计一个动态规划算法:
1. 刻画一个最优解的结构特征
2. 递归地定义最优解的值
3. 计算最优解的值,通常采用自底向上的方法
4. 利用计算出的信息构造一个最优解
1~3是动态规划算法求解问题的基础,如果仅需要一个最优解的值,可以忽略步骤4。如果需要求得一个最优解,则有时要在第3步的计算中记录一些附加信息,以便用来构造一个最优解。
1. 钢条切割
钢条切割问题
长度为n英寸的钢条共有2^(n-1)种不同的切割方案。
在该问题中,对于最优解 , 可以用更短的钢条的最优解来描述:将钢条从左边切割下长度为i的一段,只对剩下的n-i的一段进行继续切割(递归求解),而不对左边长度为i的一段在进行切割。
为了求解规模为n的原问题,可以先求解形式完全一样,但规模更小的子问题,这样,钢条切割问题满足最优子结构:问题的最优解由相关子问题的最优解组合而成,这些子问题可以独立求解。
自顶向下递归实现
Cut-Rod(p, n)
if n == 0
return 0
q = -∞
for i = 1 to n
q = max(q, p[i] + Cut-Rod(p, n - i))
return q
CUT-ROD的效率低是因为它反复求解相同的子问题
使用动态规划方法求解最优钢条切割问题
朴素递归算法效率很低,因为它反复求解相同的子问题。动态规划方法仔细安排求解,对每个子问题只求解一次,并将结果保存下来。随后再次需要此子问题的解,只需查找保存的结果,而不必重新计算。
动态规划方法是付出额外的内在空间来节省计算时间,是典型的时空权衡的例子。
动态规划有两种等价的实现方法:
1. 带备忘录的自顶向下法
Memoized-Cut-Rod(p, n)
let r[0..n] be a new array
for i = 0 to n
r[i] = -∞
Memoized-Cut-Rod-Aux(p, n , r)
Memoized-Cut-Rod-Aux(p, n, r)
if r[n] >= 0
return r[n]
if n == 0
q = 0
else
q = -∞
for i = 1 to n
q = max(q, p[i] + Memoized-Cut-Rod-Aux(p, n - i, r))
r[n] = q
return q
- 自底向上法
Bottom-Up-Cut-Rod(p, n)
let r[0..n] be a new array
r[0] = 0
for j = 1 to n
q = -∞
for i = 1 to j
q = max(q, p[i] + r[j-1])
r[j] = q
return r[n]
子问题图
当思考一个动态规划问题时,我们应该弄清所涉及的子问题及子问题之间的依赖关系。

本文深入讲解动态规划的基本概念和技术,包括最优子结构、重叠子问题等关键特性,并通过实例探讨钢条切割、矩阵链乘法、最长公共子序列等问题的解决方案。
动态规划&spm=1001.2101.3001.5002&articleId=73327640&d=1&t=3&u=d5e59fe136fe4d46b48d066ad76b2d53)
369

被折叠的 条评论
为什么被折叠?



