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

ANSWER:第15章DP(转)

 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的钢条继续切割。

               BOTTOM_UP_CUT_ROD_COST(p, n, c):  
  1.     let r[0...n] and m[0...n] be new arrays  
  2.     r[0] = 0, m[0] = 0  
  3.     for i = 1 to n  
  4.         q = -∞  
  5.         for j = 1 to i  
  6.             if q < p[j] + r[i-j] - m[i-j]*c  
  7.                 q = p[j] + r[i-j] - m[i-j]*c  
  8.                 m[i] = m[i-j] + 1  
  9.         r[i] = q  
  10.     return r[n]
 
//15.1-3带有固定切割成本的钢条切割方案
#if 0
#include <iostream>
using namespace std;
int Max(int a,int b)
{
    return a>b?a:b;
}
struct array
{
    int r;//代表最大收益
    int s;//代表切割方案
};
struct array *EXTENDED_BOTTOM_UP_CUT_ROD(int p[],int n)
{
    struct array *rs=new struct array[n];
    rs[0].r=0;
    int q;
    for (int j=0;j<n;j++)
    {
        int flag=1;//哨兵为1代表无切割。
        q=p[j];
        for (int i=0;i<j;i++)
        {
            //q=Max(q,p[i]+rs[j-i].r-1);
            if(q<=p[i]+rs[j-i].r-1)//切割固定成本c=1
            {
                q=p[i]+rs[j-i].r-1;
                rs[j+1].s=i+1;
                flag=0;//哨兵为0代表有切割。
            }
        }
        if (j==i)//i=j代表无切割
        {
            if (q<=p[i]+rs[j-i].r&&flag)
            {//无切割时注意切割方案就等于钢条长度。
                rs[j+1].s=i+1;
            }
        }
        rs[j+1].r=q;
    }
    return rs+n;
}
void PRINT_CUT_ROD_SOLUTION(int p[],int n)
{
    struct array *rs=EXTENDED_BOTTOM_UP_CUT_ROD(p,n);
    while (n>0)
    {
        cout<<(*rs).s<<" ";
        n=n-(*rs).s;
        rs=rs-(*rs).s;
    }
}
void main()
{
    const int n=10;
    int p[10]={1,5,8,9,10,17,17,20,24,30};
    cout<<(*EXTENDED_BOTTOM_UP_CUT_ROD(p,10)).r<<endl;
    PRINT_CUT_ROD_SOLUTION(p,10);
}
View Code

 

相关文章:

  • 2021-08-18
  • 2022-01-16
  • 2022-01-04
  • 2021-06-03
  • 2022-01-29
  • 2021-08-27
  • 2021-10-24
猜你喜欢
  • 2021-06-29
  • 2022-01-10
  • 2022-01-07
  • 2022-12-23
  • 2021-06-13
相关资源
相似解决方案