CLRS 15.1钢条切割

来源:互联网 发布:如何把mac里的照片导出 编辑:程序博客网 时间:2024/06/11 03:21

15.1-1
T(n)=1+j=0n1T(j)=1+T(0)+...+T(n1)
T(n1)=1+T(0)+...+T(n2)

由上面两式得 T(n)=2T(n1),通过数学归纳法可得 T(n)=2n

15.1-2
根据书中的数据,当长度为 4 的时候,每英寸的价值最高的是长度为 3 的时候,切割方案就是 3+1,得到的价值是 9。实际上不切割的价值也是 9,另外最好的切割方案是 2+2,此时的价值是 10 。

15.1-3
我们把自底向上的CUT-ROD修改一下,先将 q 设置为没有切割时的价值,然后将第二个 for 改成 for i = 1 to j - 1

MODIFIED-CUT-ROD(p, n, c)    let r[0..n] be a new array    r[0] = 0    for j = 1 to n        q = p[j]         for i = 1 to j - 1            q = max(q, p[i] + r[j - i] + c)        r[j] = q    return r[n]

运行代码

#include <iostream>#include <cstring>using std::cout;using std::endl;//参数分别表示价格表,长度,固定成本,保存切割方案数组int BOTTOM_UP_CUT_ROD(int *price,int n,int c,int *s){    int *r = new int[n+1];    *(r+0) = 0;    for(int j = 1; j <= n; ++j)    {        int q = *(price + j - 1);        *(s + j - 1) = j;        for(int i = 1; i < j; ++i)        {            int temp = *(price + i - 1) + *(r + j - i) - c;            if(q < temp)            {                q = temp;                *(s + j - 1) = i;            }        }        *(r + j) = q;    }    int ret = *(r + n);    delete []r;    return ret;}void PRINT_CUT_ROD_SOLUTION(int *s,int n){    while(n > 0)    {        cout << s[n-1] << ' ';        n -= s[n-1];    }}int main(){    int p[] = {1,5,8,9,10,17,17,20,24,30};    int s[10];    memset(s,0,sizeof(int)*10);    for(int i = 1; i < 11; ++i)    {        cout << "Length " << i << "'s price is: " << BOTTOM_UP_CUT_ROD(p,i,0,s) << endl;        cout <<  "cut rod solution is: ";        PRINT_CUT_ROD_SOLUTION(s,i);        cout << endl;    }    return 0;}

15.1-4
伪代码略,给出运行代码

#include <iostream>#include <climits>#include <cstring>using std::cout;using std::endl;//参数分别表示价格表,长度,备忘机制数组r,保存切割方案数组int MEMORIZED_CUT_ROD_AUX(int *price,int n,int *r,int *s){    if(n == 0)        return 0;    if(*(r + n -1) >= 0)        return *(r + n -1);    int q = INT_MIN;    for(int i = 0; i < n; ++i)    {        int temp = *(price + i) + MEMORIZED_CUT_ROD_AUX(price,n-i-1,r,s);        if(q < temp)        {            q = temp;            *(s + n - 1) = i + 1;        }    }    *(r + n - 1) = q;    return q;}int MEMORIZED_CUT_ROD(int *price,int n,int *s){    int *r = new int[n];    for(int i = 0; i < n; ++i)        *(r + i) = INT_MIN;    return MEMORIZED_CUT_ROD_AUX(price,n,r,s);}void PRINT_CUT_ROD_SOLUTION(int *s,int n){    while(n > 0)    {        cout << s[n-1] << ' ';        n -= s[n-1];    }}int main(){    int p[] = {1,5,8,9,10,17,17,20,24,30};    int s[10];    memset(s,0,sizeof(int)*10);    for(int i = 1; i < 11; ++i)    {        cout << "Length " << i << "'s price is: " << MEMORIZED_CUT_ROD(p,i,s) << endl;        cout <<  "cut rod solution is: ";        PRINT_CUT_ROD_SOLUTION(s,i);        cout << endl;    }    return 0;}

15.1-5
这个很简单,就直接写了,很显然是 O(n)

FIBONACCI(n)    let fib[0..n] be a new array    fib[0] = fib[1] = 1    for i = 2 to n        fib[i] = fib[i-1] + fib[i-2]    return fib[n]

子问题图包括 n+1 个顶点 v0,v1,...,vn,对 i=2,3,...,n,顶点 vn 有两条边,分别指向顶点 vi1,vi2。因此一共有 2n2 条边。

0 0
原创粉丝点击