/*
*钢条切割问题:给定一段长度为n英寸的钢条和一个价格表pi(i=1,2,...)
*(表示长度为1英寸2英寸...的钢条价格)求切割方案,使得销售收益r最大。
*注意:如果长度为n英寸的钢条价格p[n]足够大,最优解可能就是完全不需要切割
*/
#include
using namespace std;
#define MAXLENGTH 10//钢条最大长度
int rArray[MAXLENGTH+1];//动态规划方法使用过程中用到的临时数组
int pArray[MAXLENGTH+1] = {0,1,5,8,9,10,17,17,20,24,30};
int max(int a,int b);
int cutRod(const int *p,const int n);
int memoizedCutRod(const int *p,const int n);
int memoizedCutRodAux(const int *p,const int n,int *r);
int bottomUpCutRod(const int *p,const int n);
int main()
{
cout << bottomUpCutRod(pArray,MAXLENGTH) << endl;
cout << memoizedCutRod(pArray,MAXLENGTH) << endl;
cout << cutRod(pArray,MAXLENGTH) << endl;
cout << bottomUpCutRod(pArray,MAXLENGTH-1) << endl;
cout << memoizedCutRod(pArray,MAXLENGTH-1) << endl;
cout << cutRod(pArray,MAXLENGTH-1) << endl;
cout << bottomUpCutRod(pArray,MAXLENGTH-2) << endl;
cout << memoizedCutRod(pArray,MAXLENGTH-2) << endl;
cout << cutRod(pArray,MAXLENGTH-2) << endl;
system("pause >> cout");
return 0;
}
/*
*求两个数中的最大值
*输入:两个待比较的数
*输出:最大数
*/
int max(int a,int b)
{
if(a>b)
return a;
return b;
}
/*
*自顶向下的递归实现:
*输入:钢条价格数组p[1,2,3,,,,],钢条长度n
*输出:最大收益r
*/
int cutRod(const int *p,const int n)
{
if(n==0)
return 0;
int q = -1;
for(int i=1;i<=n;i++)
{
//进行了大量的重复循环计算
q = max(q,p[i] + cutRod(p,n-i));
}
return q;
}
/*
*动态规划方法求解钢条切割问题:
*1、带备忘录的自顶向下方法
*输入:钢条价格数组p[1,2,3,,,,],钢条长度n
*输出:最大收益r
*/
int memoizedCutRod(const int *p,const int n)
{
for(int i=0;i<=n;i++)
{
rArray[i] = -1;
}
return memoizedCutRodAux(p,n,rArray);
}
/*
*备忘录法就是先判断最大收益数组中的元素r[n]是否已经存在,
*如果存在就不需要再重复计算了
*/
int memoizedCutRodAux(const int *p,const int n,int *r)
{
if(r[n]>=0)
return r[n];
int q;
if(n==0)
q = 0;
else
{
q = -1;
for(int i=1;i<=n;i++)
{
q = max(q,p[i]+memoizedCutRodAux(p,n-i,r));
}
}
r[n] = q;
return q;
}
/*
*动态规划方法求解钢条切割问题:
*2、自底向上的方法
*输入:钢条价格数组p[1,2,3,,,,],钢条长度n
*输出:最大收益r
*/
int bottomUpCutRod(const int *p,const int n)
{
rArray[0] = 0;//长度为0的钢管无价值
for(int j=1;j<=n;j++)
{
int q = -1;
for(int i=1;i<=j;i++)
{
q = max(q,p[i]+rArray[j-i]);
}
//每次循环结束rArray中记录的都是长度为j的钢管的最大收益
rArray[j] = q;
}
return rArray[n];
}