首页 > 代码库 > 算法13---动态规划钢材裁剪
算法13---动态规划钢材裁剪
算法13---动态规划钢材裁剪
动态规划方法通常用来求解最优化问题。动态规划算法设计步骤:
1.刻画一个最优解的结构特征。
2.递归定义最优解的值。
3.计算最优解的值,通常采用自底向上的方法。
4.利用计算出的信息构造一个最优解。
文中给出了算法的伪代码,下面我们把递归,从顶到底,从底到顶的方法都实现一下
具体的代码如下所示
1 #include <stdio.h> 2 #include <stdlib.h> 3 4 5 6 7 #define infinity -1 //负无穷 8 #define len 100 9 10 11 12 int cut_rod(int p[],int n); 13 void print_menoized_cut_rod(int p[],int n); 14 int menoized_cut_rod_aux(int p[],int r[],int s[],int n); 15 void bottomup_cut_rod(int p[],int r[],int s[],int n); 16 void PrintCutRodSolution(int p[], int n);//自底向上法 17 18 19 //自顶向下递归实现 20 21 int cut_rod(int p[],int n) 22 { 23 int max=infinity; 24 25 if (n==0) 26 { 27 return 0; 28 } 29 30 //printf("ok,start!\n"); 31 int temp=0; 32 for (int i = 0; i < n; i++) 33 { 34 temp=p[i]+cut_rod(p,n-i); 35 if (temp>max) 36 { 37 max=temp; 38 } 39 } 40 return max; 41 } 42 43 44 /* 45 下面我们采取动态规划的方法来求主要有两种方法 46 第一种方法称为带备忘的自顶向下法。此方法按照递归方式编写过程, 47 但过程会保存每个子问题的解——用数组r[i]记录总长度为i的钢管的最大收益值。 48 当需要一个子问题的解时,过程首先检查是否已经保存过此解,如果是,直接返回保存的值, 49 否则递归计算这个子问题。 50 51 第二种方法称为自底向上法,这是动态规划的常用方法,这种方法需 52 要我们将子问题按照规模排序,按由小到大的顺序进行求解——在本题 53 中即按i从1到n的顺序求解。每个子问题只需求解一次,并及时把结果 54 记录下来,以便后面调用。 55 56 */ 57 58 59 //首先先实现备忘录方法。带备忘录的自顶向下方法 60 61 void print_menoized_cut_rod(int p[],int n) 62 { 63 int r[len]={0};//记录长度为i时的最大收益 64 int s[len]={0};//用来记录对应的切割方式 65 for (int i = 0; i < n; i++) 66 { 67 r[i]=infinity; 68 } 69 printf("the most expensive method is \n", menoized_cut_rod_aux(p,r,s,n)); 70 printf("the way to cut as follow!\n"); 71 while(n>0) 72 { 73 printf("%d\t",s[n]); 74 n-=s[n]; 75 } 76 printf("\n"); 77 } 78 79 80 int menoized_cut_rod_aux(int p[],int r[],int s[],int n) 81 { 82 int max; 83 if (r[n]>=0) 84 { 85 return r[n]; 86 } 87 if (n==0) 88 { 89 max=0; 90 } 91 else 92 { 93 max=infinity; 94 for (int i = 0; i < n; i++) 95 { 96 int temp=p[i]+menoized_cut_rod_aux(p,r,s,n-i); 97 if (temp>max) 98 { 99 max=temp;100 s[n]=i;101 }102 }103 }104 return max;105 }106 107 //由底到顶的方法108 void PrintCutRodSolution(int p[], int n)109 {110 int r[len]={0};111 int s[len]={0};112 bottomup_cut_rod(p,r,s,n);113 printf("the most value cut method solve by bottom to up:%d\n",r[n] );114 printf("the cut method:\n");115 while(n>0)116 {117 printf("%d\t",s[n]);118 n-=s[n];119 }120 printf("\n");121 }122 123 124 void bottomup_cut_rod(int p[],int r[],int s[],int n)125 {126 int max;127 for (int i = 0; i <= n; i++)128 {129 max=infinity;130 for (int j = 1; j <= n;j++)131 {132 if (max>p[j]+r[i-j])133 {134 max=p[j]+r[i-j];135 s[i]=j;136 }137 }138 r[i]=max;139 }140 }141 142 143 144 int main()145 {146 int p[10]={1,5,8,9,10,17,17,20,24,30};147 int n=4;148 // 先递归得出结果149 int ans=cut_rod(p,n);150 151 printf("the most benifit is %d\n", ans);152 // 按照从底到顶的方法153 PrintCutRodSolution(p,n);154 printf("\n");155 //按照从顶到底,备忘录法156 print_menoized_cut_rod(p,n);157 return 0;158 }
算法13---动态规划钢材裁剪
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。