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