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

来自为知笔记(Wiz)

时间: 2024-10-18 23:09:14

1、钢条切割问题的相关文章

c++实现钢条切割问题

今天看了算法导论里面的动态规划(DP),有个有意思的问题:钢条切割来获取最大的收益. 书中讲到了几种求解方法,包括递归求解法.备忘录DP解法.自底向上的解法以及对解的重构.书中给出不同解法的伪码,刚好需要练习c++,就有c++来实现DP求解钢条切割问题. [递归求解] // 钢条切割问题 // 自顶向下 递归实现 #include <iostream> #include <time.h> using namespace std; int cut_rod(int len, int p

《算法导论》中动态规划求解钢条切割问题

动态规划算法概述 动态规划(dynamic programming)1是一种与分治方法很像的方法,都是通过组合子问题的解来求解原问题.不同之处在于,动态规划用于子问题重叠的情况,比如我们学过的斐波那契数列.在斐波那契数列的求解问题中,我们经常要对一个公共子问题进行多次求解,而动态规划算法,则对每个子问题只求解一次,将其解保存在一个表格中,从而避免了大量的冗余计算量. 动态规划算法常用于寻找最优解问题(optimization problem).而其规划大概可分为四步: 1.刻画一个最优解的结构特

算法导论--动态规划(钢条切割)

钢条切割问题 现有一段长度为n英寸的钢条和一个价格表pi,求切割方案使销售利益最大rn最大 长度为n英寸的钢条共有2n?1种不同的切割方案,因为可以每个整英寸的位置都可以决定切割或者不切割. 为了得到rn最大,可以把这个问题分成子问题求解,先切一刀,再考虑余下的部分的最大收益即求 rn=max{pk+rn?k}(k=1,2,3-n-1), pk部分不进行继续切割,直接作为一个整体售出 ; rn?k部分继续切割,考虑所有的情况,分成子问题. 求出所有k值对应的收益最大者作为rn 也有可能不进行任何

算法导论-动态规划-钢条切割

动态规划通常用于解决最优化问题,在这类问题中,通过做出一组选择来达到最优解.在做出每个选择的同时,通常会生成与原问题形式相同的子问题.当多于一个选择子集都生成相同的子问题时,动态规划技术通常就会很有效,其关键技术就是对每个这样的子问题都保存其解,当其重复出现时即可避免重复求解. 钢条切割问题 Serling公司购买长钢条,将其切割为短钢条出售.切割工序本身没有成本支出.公司管理层希望知道最佳的切割方案.假定我们知道Serling公司出售一段长为i英寸的钢条的价格为pi(i=1,2,…,单位为美元

算法导论读书笔记之钢条切割问题

算法导论读书笔记之钢条切割问题 巧若拙(欢迎转载,但请注明出处:http://blog.csdn.net/qiaoruozhuo) 给定一段长度为n英寸的钢条和一个价格表 pi (i=1,2, -,n),求切割钢条的方案,使得销售收益rn最大.注意,如果长度为n英寸的钢条价格pn足够大,最优解可能就是完全不需要切割. 若钢条的长度为i,则钢条的价格为Pi,如何对给定长度的钢条进行切割能得到最大收益? 长度i   1   2    3   4     5      6     7     8  

动态规划 钢条切割问题

#include <stdio.h> /* *钢条切割问题: *问题描述 假设公司出售一段长度为i英寸的钢条的价格为Pi(i = 1, 2, ...单位:美元),下面给出了价格表样例: 长度i 1 2 3 4 5 6 7 8 9 10 价格Pi 1 5 8 9 10 17 17 20 24 30 切割钢条的问题是这样的:给定一段长度为n英寸的钢条和一个价格表Pi,求切割方案,使得销售收益Rn最大. */ //假定价格一开始已经给出了,用全局的写死 #define max(x,y) (x)>

动态规划 -- 钢条切割

/* 动态规划和分治法相似,都是通过组合子问题的解来求解原问题. 但分治法是将 问题划分为互不相交的子问题,递归地求解子问题,再将它们的解组合起来,求出 原问题的解.与之相反,动态规划应用于子问题重叠的情况,即不同的子问题具有公共的 子问题.在这种情况下,分治法会做很多不必要的工作. 动态规划方法通常用来求解最优化问题,这类问题通常有很多可行解.我们希望寻找 具有最优值的解. 我们通常按照如下4个步骤来设计一个动态规划算法: · 刻画一个最优解的结构特征 · 递归地定义最优解的值 · 计算最优解

钢条切割问题求解方法及相关思考

钢条切割问题求解方法及相关思考 题目来源于<算法导论>第15章第一节.问题如下: 给定一个长度为n英寸的钢条和一个价格表pi(i=1,2,3,...n),求能够使销售收益rn最大的切割方案. 问题1:一共有多少种切割方式? 思路一:对于一个长度为n英寸的钢条,其中一共有n-1个节点可供切割,在每一个节点处都可以选择切割或者不切割,将对一根钢条的切割过程视为从第一个节点直到第n-1个节点逐一选择切割或者不切割的一个过程,利用乘法原理,可以算出来总共有2n-1种切割方案.以四个节点的钢条为例: 思

算法导论---------动态规划之钢条切割

动态规划方法通常用来求解最优化问题.动态规划算法设计步骤: 1.刻画一个最优解的结构特征. 2.递归定义最优解的值. 3.计算最优解的值,通常采用自底向上的方法. 4.利用计算出的信息构造一个最优解. 动态规划的实现方法: 带备忘的自顶向下法:此方法仍按自然的递归形式编写过程,但过程会保存每个子问题的解(通常保存在一个数组或散列表中).当需要一个子问题的解时,过程首先检查是否已经保存过此解.如果是,则直接返回保存的值,从而节省了计算时间:否则,按通常方式计算这个子问题. 自底向上法:这种方法一般