• 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、原问题的解可以分解成许多子问题的解得到。
        








  • 相关阅读:
    [LuoguP2161] 会场预约
    [LuoguP1198] 最大数
    [LuoguP1484] 种树
    [LuoguP1801] 黑匣子
    [LuoguP1196]银河英雄传说
    [LuoguP1345] 奶牛的电信Telecowmunication
    [LuoguP1119]灾后重建
    【笔记】一元函数微分学
    【复习】Listening and Reading Comprehension
    【笔记】一元函数的不定积分
  • 原文地址:https://www.cnblogs.com/yml435/p/4655544.html
Copyright © 2020-2023  润新知