1、钢条切割问题

钢条切割问题的两种解法

  1. #ifndef IRON_CUT_PRB_H
  2. #define IRON_CUT_RPB_H
  3. #include <iostream>
  4. int ironCutPrb(int *ironPrice,int Length); //这个是基于递规逄法的
  5. int ironCutPrb_optimize(int *ironPrice,int Length); //这个是基于双层循环的。

  6. #endif
  1. #include"ironCutPrb.h"
  2. #define Max(a,b) a>b? a:b
  3. int storePre[100]={0};
  4. int ironCutPrb(int *ironPrice,int Length){
  5. if(Length==0)
  6. return 0;
  7. if(storePre[Length]!=0)
  8. return storePre[Length];
  9. int price=-245;
  10. for(int i=1;i<=Length; i++){
  11. price=Max((ironPrice[i]+ironCutPrb(ironPrice,Length-i-1)),price);
  12. }
  13. storePre[Length]=price;
  14. return price;
  15. }
  16. int ironCutPrb_optimize(int *ironPrice,int Length){
  17. int *cutIndex=new int[Length+1];
  18. int *priceStore=new int[Length+1];
  19. int *pathStore=new int[Length+1];
  20. for(int i=0;i<=Length; i++){
  21. pathStore[i]=0;
  22. }
  23. priceStore[0]=0;
  24. for(int i=1;i<=Length; i++){
  25. int price=-200;
  26. int j;
  27. for(j=1;j<=i; j++){
  28. if(priceStore[i-j]+ironPrice[j-1]>price){
  29. pathStore[i]=j; //意思为使是长度为i的钢条价格达到最优,需要从第j个位置进行截断,当然
  30. //可能还有其它的位置呢。
  31. }
  32. price=Max(price,(priceStore[i-j]+ironPrice[j-1]));
  33. }
  34. priceStore[i]=price;
  35. }
  36. int n=Length;
  37. while(n>0){
  38. std::cout<<pathStore[n]<<std::endl;
  39. n=n-pathStore[n];
  40. }
  41. return priceStore[Length];
  42. }


在以前我们学过的分治算法问题,那么分治算法问题的思想是把原问题分解成很多的小问题,而这些小问题和原问题有着一点联系,而且它们的解法是差不多的。
如我们以前注意过的背包问题,那么一个容量为50的背包如何选择商品使得它的价值最大,那么一个容量为50的背包,可以不停地由子问题原来是容量为50,可以
选3种商品,而子问题便是容量从0到49,选择商品由0到3.。。。然后在这些问题的基础上求解得以原问题。。
但是有一点不好的是,分治思想仅仅是解决了问题,但是没有去优化问题,如何使得时间、空间复杂度最小,于是便产生了动态规划,动态规划的思想是将这此子问题保存
下来,然后当碰到相同的问题时,就不需要去再求,直接查表就得了。
在本钢条切割问题中我们看关键代码如下:
  1. for(int i=1;i<=Length; i++){
    price=Max((ironPrice[i]+ironCutPrb(ironPrice,Length-i-1)),price);
    }
我们可以看到,我们采用的主法是固定一边不动,另一边进行最优化处理,也许你最初会想这样解决问题,不就是把原问题解成子问题求最优解嘛,如下
   
  1. for(int i=1;i<=Length; i++){
  2. price=Max(price,ironCutPrb(ironPrice,Length-i)+ironCutPrb(ironPrice,i));
  3. }
呵呵,看起来还挺有道理的,就是把原问题分成两个子问题嘛。。。但是你想想,问你用上己知条件ironPrice数组了没有,,,,,!!压根就没用过。。。是的。。
这个怎么把己知与未知的桥梁建立起来呢?这可是解决问题的一般套路。。。嗯。。是的。其实这个想法是可以的。但是在这种情况下不行,至少对于本问题的
解法是不行的。于是我们采用了固定一边,优化另一边的方法,这样我们使用
 price=Max((ironPrice[i]+ironCutPrb(ironPrice,Length-i-1)),price);
恰好我们利用了ironPrice数组,而且想想也是可以的。选择从左往右优化的方法,而且最主要的是我们这里钢条切割问是与位置无关的,也就是说价格只与钢条的
长度有关,与你从哪里切下来的没有半毛钱的关系。。。。呵呵。。。

其实于对我而言,动态规划问题或者分治算法的思想是:1、原问题的最优解是由许多子问题的最优解叠加得到。2、原问题的解可以分解成许多子问题的解得到。
    








原文地址:https://www.cnblogs.com/yml435/p/4655544.html