面试题14:剪绳子

1 题目

有一个长度为n的绳子,请把绳子剪成m段(m、n都是整数,n>1且m>1)每段绳子的长度记为k[0]、k[1]...k[m-1],求每一段相乘最大为多少?

2 思路

  1. 在剪第一刀的时候,我们有n-1种可能选择,分别是1,2,3,,n-1.因此f(n)=max(f(i)f(n-i))。
  2. 由于是自上而下递归,将会产生许多重复的子问题。为了避免重复计算。选择自下而上计算。

3 代码

int maxProductAfterCutting_solution(int length)
{
	if (length<1)
		return 0;
	if(length<2)
		return 1;
	if(length<3)
		return 2;
	int *products = new int[length+1];
	products[0]=0;
	products[1]=1;
	products[2]=2;
	products[3]=3;
	int max =0;
	// 自下向上遍历,求各个长度为n的绳子的最佳间断策略
	for(int i =4 ;i <=length;i++)
	{
		// 求长度为i时,最佳间断策略
		max=0;
		for(int j=0;j<=i/2;j++)
		{
			int product=products[j]*products[i-j];
			if(product>max)
			{
				max=product;
			}
		}
		products[i]=max;
	}
	max = products[length];
	delete[] products;
	return max;
}

数组中第i个元素表示把长度为i的绳子,剪成若干段后,各段乘机的最大值,即为f(i),所以上式代码中,数据长度为length+1,且第一个循环是“≤length”。

4 动态规划特点

  1. 是求解一个最优解
  2. 整体问题的最优解依赖于子问题的最优解
  3. 子问题之间还有相互重叠的更小的子问题。
  4. 由上往下分析,从下向上求解问题。
posted @ 2021-03-30 09:48  一地斜阳  阅读(47)  评论(0)    收藏  举报