算法导论15.1钢条切割 练习总结

来源:互联网 发布:c语言vector用法 编辑:程序博客网 时间:2024/05/17 17:15

15.1-1 由公式(15.3)和初始条件T(0) = 1,证明公式(15.4)成立。

ANSWER:


15.1-2 举反例证明下面的“贪心”策略不能保证总是得到最优切割方案。定义长度为i的钢条的密度为Pi / i,即每英寸的价值。贪心策略将长度为n的钢条切割下长度为i (1 ≤ i ≤ n)的一段,其密度最高。接下来继续使用相同的策略切割长度为n-i的剩余部分。

ANSWER:当长度n = 4时,按照“贪心”策略则切割成长度为1和3的钢条(p = 1 + 8 = 9);而最优解为切割成2条长度为2的钢条(p = 5 + 5 = 10 > 9)。


15.1-3 我们对钢条切割问题进行一点修改,除了切割下的钢条段具有不同价值Pi外,每次切割还要付出固定的成本c。这样,切割方案的收益就等于钢条段的价格之和减去切割成本。设计一个动态规划算法解决修改后的钢条切割问题。

ANSWER:多新建一个数组m[0...n]记录每个长度的钢条最优解的切割段数,当完成长度为i的钢条最优解时,更新长度为i+1时使m[i+1] = m[j] + 1,其中长度为i+1的钢条切割成长度为(i+1-j)和j的两大段,长度为j的钢条继续切割。

<span style="font-size:18px;"><span style="font-size:18px;">BOTTOM_UP_CUT_ROD_COST(p, n, c):    let r[0...n] and m[0...n] be new arrays    r[0] = 0, m[0] = 0    for i = 1 to n        q = -∞        for j = 1 to i            if q < p[j] + r[i-j] - m[i-j]*c                q = p[j] + r[i-j] - m[i-j]*c                m[i] = m[i-j] + 1        r[i] = q    return r[n]</span></span>

15.1-4 修改MEMOIZED-CUT-ROD,使之不进返回最优收一只,还返回切割方案。

ANSWER:利用数组s的结果可以得到切割方案,新建存储长度为n的钢条切割方案数组t[0...n]

<span style="font-size:18px;"><span style="font-size:18px;">CUT_WAY(s, n):    i = 0    while n > 0        t[i] = s[n]        n = n - s[n]        i = i + 1    return t[0...i-1]</span></span>

15.1-5 斐波那契数列可以用递归式(3.22)定义。设计一个O(n)时间的动态规划算法计算第n个斐波那契数。画出字问题图。图中有多少顶点和边?

ANSWER:O(n)时间,O(1)空间

<span style="font-size:18px;"><span style="font-size:18px;">On_for_Fibonacci_sequence(n):    if n <= 2        return 1    x = 1, y = 1    for i = 3 to n        res = x + y        x = y        y = res    return res</span></span>
子问题图:

图中有n个顶点,(2n-3)条边。

0 0