剑指offer8:剪绳子问题(动态规划和贪婪算法)

内容:

给定一根长度为n的绳子,请把绳子剪成m段,每段绳子记为k[0],k[1]……k[m]。请问k[0]*k[1]……*k[m]可能的最大乘积是多少?例如:当绳子长度为8时,我们把它剪成长度分别为2,3,3段,此时最大乘积为18.

解题思路:

思路一:我们先考虑能否把大问题分解成小问题,分解后的小问题也存在最优解,如果把小问题的最优解组合起来能否是整个问题的最优解,这就是动态规划求解。我们把绳子从第i(i

代码实现:

int maxlength(int a[],int length)
{
        if (length < 2)
		return 0;
	if (length == 2)
		return 1;
	if (length == 3)
		return 2;
		int i = 4;
		while (i <= length){
			int j = 1;
			while (j <= i / 2){
				if (a[j] * a[i - j]>a[i])     
					a[i] = a[j] * a[i - j];
				j++;
			}
			i++;
		}
		
		return a[length];
	}
main()函数中传入的数组的初始化值应该是{0,1,2,3},并且长度大于绳子的长度

思路二:

从问题的某一个初始解出发逐步逼近给定的目标,以尽可能快的地求得更好的解。当达到某算法中的某一步不能再继续前进时,算法停止,这就是贪婪算法。在剪绳子中,如果绳子的长度大于5,则每次剪出的长度为3的绳子。如果剩下的长度仍然大于5,则接着剪出一段长度为3的绳子,重复这个步骤,直到剩下的长度小于5.时间和空间复杂度都为O(1)。

代码实现:

int maxlength(int length)
{
	if (length < 2)
		return 0;
	if (length == 2)
		return 1;
	if (length == 3)
		return 2;
	int timesOf3 = length / 3;    //剪长度为3的绳子段
	if ((length - timesOf3 * 3)==1)   //当长度为4的时候不能去用3剪
		timesOf3 -= 1;      
	int timesOf2= (length - timesOf3* 3) / 2;     // 这时应该把绳子剪成长度为2的两段:2*2>1*3
	return ((int)(pow(3, timesOf3))*((int)pow(2, timesOf2)));
}

你可能感兴趣的:(C语言)