动态规划

适用于动态规划解决的问题所具有的特点:

1、求得一个问题的最优解

2、整体问题的最优解依赖于子问题的最优解

3、把大问题划分为若干小问题,这些小问题还有相互重叠的更小的子问题

4、问题可以自上而下分析,要从下而上求解

 

 

题目一:

       一段长为n的绳子,把绳子剪为m段(m,n都是整数,n>1 并且 m>1),每段绳子的长度记为 K0,K1,...,Km。请问 K0*K1*...*Km的最大乘积是多少(m不确定)? 例如:长为8的绳子切为2,3,3这三段,得到最大为18。

分析:

       这是个动态规划问题,定义 f(n)为长度n的绳子剪为若干段乘积的最大值。在剪第一刀时有 n-1中结果,也就是说剪出来的绳子可能是1,2,3,4,...5,6,n-1 这些种可能长度。f(2)最大值为 1x1=1, f(3) = 1x2 = 2 > 1x1x1。

       此问题的递推公式为: f(n) = max( f(i)*f(n-i) ) 方程说明:长为 n的绳子切第一刀,切为两部分,则第一刀下去就有总体的最长长度;再切第二刀...;直到绳子长为 1时,则再切一刀,最大乘积为0

代码实现:

int maxAfterCutting(int length)
{
	if (length < 2)
		return 0;
	if (length == 2)
		return 1;
	if (length == 3)
		return 2;

	int *products = new int[length + 1];  //保存4~length 各个绳子长度情况下,乘积的最大值;多申请一个节点,则products[length]保存绳子长度为length的乘积最大值

	//绳子长为0~3的情况已经在上述处理过,所以这4个位置比较特殊,为4个辅助位置
	//当长度为4的绳子,切为(1和3)两段时,值就是1x3;切为(2和2)两段时,值就是2x2,这4个初始值刚好满足需求
	products[0] = 0; //这个值用不到,可以不初始化;因为j<=i/2,则i-j 永远不可能等于0
	products[1] = 1;
	products[2] = 2;
	products[3] = 3;

	int max = 0;
	for (int i = 4; i <= length; i++) //绳子长为 0~3 的情况在上诉的三个 if 中已经求得,程序从绳子长为4开始求解
	{
		//求解绳子长度为 i的最大值,f(n) = max( f(t)*f(n-t) )
		max = 0; //默认各个长度对应的乘积初始都是0
		for (int j = 1; j <= i / 2; j++) //j == i/2 时说明是在绳子中间切的,则此边界位置的两边计算一遍就好了
		{
			int product = products[j] * products[i - j]; //j 和 i-j 两段
			if (max < product) //产生了更大的值,就替换掉max
				max = product;

			products[i] = max;
		}
	}

	max = products[length];
	delete[] products;
	return max;
}

上述代码执行的一个手动过程,方便理解代码:

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值