动态规划_钢条切割最优策略

/*
 *钢条切割问题:给定一段长度为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];
}

你可能感兴趣的:(数据结构与算法(C++实现))