当前位置:   article > 正文

动态规划--钢条切割的C++实现_钢条切割 有费用!!!!!!! 动规 c++

钢条切割 有费用!!!!!!! 动规 c++

在《算法导论》动态规划那章,讲述了一个应用动态规划的例子--钢条切割。

钢条切割的问题是这样的:给定一段长度为n英寸的钢条和一个价格表(i=1,2,...,10),求切割钢条方案,使得销售收益最大。

我们可以采用一种简单的递归求解方法:我们将钢条从左边切割下长度为i的一段,只对右边剩下的 长度为n-i的一段继续进行切割(递归求解),对左边的一段则不再进行切割。用公式可以表示为:

方法一:带备忘的自顶向下法。

此方法按自然的递归形式编写过程,但过程会保存每个子问题的解,这里我们保存在数组r中。当需要一个子问题的解时,过程首先检查是否已经保存过此解。如果是,则直接返回保存的值,从而节省计算时间;否则,按通常形式计算这个子问题。我们称这个递归过程是带备忘的(memoized),因为它“记住”了之前已经计算的结果。代码如下:

  1. #include<iostream>
  2. using namespace std;
  3. //对应于长度为1,2...10的钢条价格表
  4. int p[10]={1,5,8,9,10,17,17,20,24,30};
  5. //返回两个数的较大值
  6. int max(int a,int b)
  7. {
  8. return (a>b)?a:b;
  9. }
  10. /*首先检查所需值是否已知,如果是,则直接返回保存的值。
  11. 否则,用通常方法计算所需值q,然后将此值存入r[n]。值得注意的
  12. 是,笔者在此处没有对钢条的长度n进行限制,所以n可能大于10,
  13. 于是增加了自己的判断,若n大于10,则计算n-10的子序列*/
  14. int MemoizedCutRodAux(int p[],int n,int r[])
  15. {
  16. if(r[n]>=0)
  17. return r[n];
  18. int q;
  19. if(n==0)
  20. q=0;
  21. else
  22. {
  23. q=-1;
  24. for(int i=0;i<n;i++)
  25. {
  26. if(i<10)
  27. q=max(q,p[i]+MemoizedCutRodAux(p,n-1-i,r));
  28. else
  29. q=max(q,r[10]+MemoizedCutRodAux(p,n-1-10,r));
  30. }
  31. }
  32. r[n]=q;
  33. return q;
  34. }
  35. int main()
  36. {
  37. int n;
  38. cout<<"请输入钢条的长度:";
  39. cin>>n;
  40. //将辅助数组的r[0..n]元素均初始化为-1
  41. int *r=new int[n+1];
  42. for(int i=0;i<=n;i++)
  43. {
  44. r[i]=-1;
  45. }
  46. int sum=MemoizedCutRodAux(p,n,r);
  47. cout<<"最大收益为:"<<sum<<endl;
  48. return 0;
  49. }
运行结果:

方法二:自底向上法

这种方法一般需要恰当定义子问题规模的概念,使得任何子问题的求解都只依赖于“更小的”子问题的求解。因而我们可以将子问题按规模排序,按由小至大的顺序进行求解。当求解某个子问题时,它所依赖的那些更小的子问题都已求解完毕,结果已经保存。每个子问题只需求解一次,当我们求解它时,它的所有前提子问题都已经求解完成。

  1. #include<iostream>
  2. using namespace std;
  3. //对应于长度为1,2...10的钢条价格表
  4. int p[10]={1,5,8,9,10,17,17,20,24,30};
  5. //返回两个数的较大值
  6. int max(int a,int b)
  7. {
  8. return (a>b)?a:b;
  9. }
  10. /*首先创建一个新数组r来保存子问题的解,然后将r[0]初始化为0,因为长度为0的钢条没有收益
  11. 接着对j=1,2,...,n按升序求解每个规模为j的子问题。将规模为j的子问题的解存入r[j]。最后返回r[n],即最优解*/
  12. int BottomUpCutRod(int p[],int n)
  13. {
  14. int *r=new int[n+1];
  15. r[0]=0;
  16. for(int j=1;j<=n;j++)
  17. {
  18. int q=-1;
  19. for(int i=0;i<=j;i++)
  20. {
  21. if(i<10)
  22. q=max(q,p[i]+r[j-i-1]);
  23. else
  24. q=max(q,r[10]+r[j-10-1]);
  25. }
  26. r[j]=q;
  27. }
  28. return r[n];
  29. }
  30. int main()
  31. {
  32. int n;
  33. cout<<"请输入钢条的长度:";
  34. cin>>n;
  35. int sum=BottomUpCutRod(p,n);
  36. cout<<"最大收益为:"<<sum<<endl;
  37. return 0;
  38. }

运行结果为:



声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/weixin_40725706/article/detail/691531
推荐阅读
相关标签
  

闽ICP备14008679号