动态规划中的钢条分割介绍与理解(自顶向下,自底向上4种包含c源代码)

标签:
算法导论c语言图片it娱乐 |
分类: 数据结构和算法导论 |
动态规划与分治法:
动态规划方法常用来解决最优问题,动态规划算法步骤如下:
钢条切割问题:
长度 i:
http://s1/mw690/002cacfOgy6Ma9KI14kf0&690
http://s2/mw690/002cacfOgy6Ma9LjZF7a1&690
#include<
stdio.h>
int arr[11]={0,1,5,8,9,10,17,17,20,24,30};
void personal(int b);
//static int q;
int k=0,w;
//
int MAX(int m,int n)
{
return m>n?m:n;
}
//普通的自底向上递归;
int CUT_ROD(int *p,int n)
{
if(n==0)
{
return 0;
}
int q=-1;
for(int i=1;i<= n;i++)
{
q=MAX(q,p[i]+CUT_ROD(p,n-i));
}
return q;
}
//带备忘的自顶向下法
int MEMOIZED_CUT_ROD_AUX(int *p,int n,int *r)
{
int q=-1;
if(r[n]>=0)
{
return r[n];
}
if(n==0)
else
for(int i=1;i<= n;i++)
{
q=MAX(q,p[i]+MEMOIZED_CUT_ROD_AUX(p,n-i,r));
}
r[n]=q;
return q;
}
//辅助函数初始化;
int MEMOIZED_CUT_ROD(int *p,int n)
{
int r[11];
for(int i=0;i<= n;i++)
{
r[i]=-1;
}
return MEMOIZED_CUT_ROD_AUX(p,n,r);
}
//自底向上的递归;
int BUTTOM_CUT_ROD(int *p,int n)
{
int r[11];
r[0]=0;
int q;
for(int j=1;j<= n;j++)
{
q=-1;
for(int i=1;i<= j;i++)
{
q=MAX(q,p[i]+r[j-i]);
//printf("#%d,",j);
}
r[j]=q;
}
return q;
}
int EXTENDED_BOTTOM_UP_CUT_ROD(int *p,int n)
{
int r[11],s[11];
r[0]=0;
int q;
for(int j=1;j<= n;j++)
{
q=-1;
for(int i=1;i<= j;i++)
{
q=p[i]+r[j-i];
s[j]=i;
// printf("#%d,%d\n",s[j],n-s[j]);
}
r[j]=q;
}
for(int j=1;j<= n/2;j++)
{
printf("切割分法#%d,%d,收益%d\n",s[j],n-s[j],p[j]+p[n-j]);
if(k
{
k=p[j]+p[n-j];
w=j;
}
}
int main()
{
int b;
printf("请输入需要切割的钢条长度(<=10)\n");
//如果想扩大,就先扩大价格数组就可以啦!
while(scanf("%d",&b)!=EOF)
personal(b);
printf("普通的自顶向下的最优收益:%d\n",CUT_ROD(arr,b));
printf("带备忘的自顶向下的最优收益:%d\n",MEMOIZED_CUT_ROD(arr, b));
printf("普通的自底向上的最优收益:%d\n",BUTTOM_CUT_ROD(arr, b));
printf("重构的自底向上%d切割成 -和
-:最优收益:%d\n",b,w,b-w,EXTENDED_BOTTOM_UP_CUT_ROD(arr, b));
return 0;
}
void personal(int b)
{
for(i=0;i<=b;i++)
{
for(j=b-i;j>0;j--)
{
if(b==i+j&&i<=b/2)
{
sum[i]=arr[i]+arr[j];
printf("%d切割成 -和 -:收益为 =\n",b,i,j,sum[i]);//打印是为了能够更加清晰地知道切割的数目与结果;
}
}
}
总结:动态规划钢条切割运用的递归解决问题,或者说是分解问题为子问题;这也让我们对递归有了更加深刻的理解与认识;相比我的开始单独编写的程序,我编写的程序是只能解决只能将钢条分成两部分的解决方法;而书本中的是将钢条分割成n个都能够实现;我从中也能够很清晰的了解到递归解决实际问题的强大;递归典型的将问题分解为子问题,代码简单清晰明了,只是需要改进的是它的时间复杂度就相对比较大;希望能够通过后面的学习想到一些方法去优化它;如有改进和错误希望帮忙留言指出!