算法导论15章习题

来源:互联网 发布:2030男女比例真实数据 编辑:程序博客网 时间:2024/05/22 04:52

15.1-1

由公式(15.3)的初始条件T(0)=1证明公式(15.4)成立

(1)T(N)=T(0)+T(1)+…T(N-1)=>T(N+1)=(2)T(0)+T(1)+…T(N-1)+T(N)
(2)-(1)即可推出
T(N+1)=2T(N)

T(2)=2T(1)
T(1)=2T(0)

=>T(N)=2^N

15.1-2

证明贪心策略( Pi/i)不能总保证得到最优切割方案

这里写图片描述

假如 长度n=4 ,那么 1 2 3 4中密度最高的 是 P3/3=2.68
根据贪心策略 会选择 1+3的切割方案。
而最好的切割策略是 2+2
此时并不能保证贪心策略取得最优解。

15.1-3

增加固定成本c再设计一个算法解决

#include<iostream>using namespace std;int r[11];//存储各种长度对应的最优收益int s[11];//存储第一次切割长度 const int c = 1; //切割成本int CUT_ROD(int n[], int); //定义递归函数参数是价格数组和钢管长度void PRINT_CUT_SOLUTION(int p[],   int n);//打印出切割长度列表int main(){    int p[11] = { -100,1,5,8,9,10,17,17,20,24,30 };  //存储价格的数组从标1开始。    int k; //输入钢管长度 k    cout << "请输入钢管长度:";    cin >> k;    int m = CUT_ROD(p, k);    cout << "总价值为:";    cout << m << endl;    cout << "输出切割方案:";    PRINT_CUT_SOLUTION(p, k);    cout << "切割次数:";    system("pause");}int CUT_ROD(int p[], int n){    int q = -1000;    r[0] = 0;    r[1] = 1;    int i, j, m;    for (j = 2; j <= n; j++)    {          int flag = 1; //定义哨兵        q = -10000;        for (i = 1; i <j; i++)        {            if (q <= p[i] + r[j - i]-c)            {                q = p[i] + r[j - i]-c; //利用已知的最优解来求大范围的最优解。                s[j] = i;                flag = 0;            }        }        if (j == i)        {            if (q <= p[j]&&flag )            {                q = p[i];                s[j] = i;            }        }        r[n] = q;    }    return r[n];}void PRINT_CUT_SOLUTION(int p[], int n){    int j = 0;    while (n > 0)    {        cout << s[n] << ' ';        n = n - s[n];    }    cout << endl;}

15.1-4

修改算法使其还返回返回切割方案

#include<iostream>using namespace std;int r[11];//存储各种长度对应的最优收益int s[11];//存储第一次切割长度int CUT_ROD(int n[], int); //定义递归函数参数是价格数组和钢管长度void PRINT_CUT_SOLUTION(int p[], int n);//打印出切割长度列表int main(){    int p[11] = {-100,1,5,8,9,10,17,17,20,24,30};  //存储价格的数组从标1开始。    int k; //输入钢管长度 k    cout << "请输入钢管长度:";    cin >> k;    int m = CUT_ROD(p, k );    cout << "总价值为:";    cout << m << endl;    cout << "输出切割方案:";    PRINT_CUT_SOLUTION(p, k);    system("pause");}int CUT_ROD(int p[], int n){    int q=-1000;    r[0] = 0;    int i,j,m;     for ( j = 1; j <= n; j++)    {        q = -10000;        for (i = 1; i <=j; i++)        {            if (q < p[i] + r[j - i])            {                q = p[i] + r[j - i]; //利用已知的最优解来求大范围的最优解。                s[j] = i;            }                                    }         r[j] = q;    }    return r[n];}void PRINT_CUT_SOLUTION(int p[], int n)//打印切割方案{    while (n > 0)    {        cout << s[n]<<' ';        n = n - s[n];    }}

这里写图片描述

15.1-5

设计一个O(N)的算法解决裴波那契数列算法