【刷题】P94剑指offer:动态规划与贪婪算法:面试题14:剪绳子

动态规划与贪婪算法

可以应用动态规划求解的问题具备以下三个特点:

1、求一个问题的最优解
2、整体问题的最优解是依赖各个子问题的最优解
3、把大问题分解成若干个小问题,这些小问题之间还有相互重叠的更小的子问题
4、从上往下分析问题。从下往上求解问题。
这是由于子问题在分解大问题的过程中重复出现,为了避免重复求解子问题,我们可以用从下往上的顺序先计算小问题的最优解并存储下来,再以此为基础求取大问题的最优解。

面试题14:剪绳子

题目:
给你一根长度为n的绳子,请把绳子剪成m段(m, n都是整数,n > 1并且m > 1),每段绳子的长度记为k[0],k[1],k[m],请问k[0]×k[1]×…×k[m]可能的最大乘积是多少吗?
例如,当绳子的长度是8时,我们把它剪成长度分别为2、3、3的三段,此时得到的最大乘积是18。

O(n^2)时间和O(n)空间的动态规划思路

/***************动态规划算法*****************/
int MaxProductAfterCutting_Solution(int length)
{
    
    
	//定义当绳长小于2时,最大的乘积
	if (length < 2)
		return 0;
	//当绳长等于2时,最大的乘积
	if (length == 2)
		return 1;
	//当绳长等于3时,最大的乘积
	if (length == 3)
		return 2;

	//当剩下的绳长分别是0/1/2的时候,最大乘积就是本身的长度,不需要再去剪,因为一刀没有不剪的乘积大
	int* product = new int[length + 1];
	product[0] = 0;
	product[1] = 1;
	product[2] = 2;
	product[3] = 3;

	int Max_Value = 0;

	for (int i = 4; i <= length; ++i)
	{
    
    
		Max_Value = 0;

		//计算绳长为i时的最大乘积
		//因为要计算f(i)乘以f(i-j)的最大值,j超过一般是就重复
		for (int j = 1; j <= i / 2; ++j)
		{
    
    
			int products = product[j] * product[i - j];

			//如果最大乘积比当前的最大值还要大
			if (Max_Value < products)
				//将绳长为i的最大乘积记录下来
				Max_Value = products;
		}
		//更新记录表中的最大乘积
		product[i] = Max_Value;
	}

	Max_Value = product[length];
	delete[] product;
	return Max_Value;
}

int main()
{
    
    
	int length = 9;
	int result = MaxProductAfterCutting_Solution(length);
	cout << "此时得到的最大乘积是:" << result << endl;
	return 0;
}

O(1)时间和空间的贪婪算法思路

/*****************贪婪算法*****************/
int MaxProductAfterCutting_Solution(int length)
{
    
    
	//当绳长不超过2时的最大乘积
	if (length < 2)
		return 0;
	//当绳长为2时的最大乘积
	if (length == 2)
		return 1;
	//当绳长为3时的最大乘积
	if (length == 3)
		return 2;

	/*********当绳长超过5时,尽可能多地把绳子剪成长度为3**********/
	//绳长为3的绳子段数
	int timesof3 = length / 3;

	//当剩下的绳长恰好为4时,则不能再剪去3,最优的解释将绳长为4剪成2*2
	//如果剩下绳长为1
	if (length - timesof3 * 3 == 1)
		timesof3--;//留下一段长度为3的绳长

	//绳长为3的绳子段数
	int timesof2 = (length - timesof3 * 3) / 2;

	//绳子的最大乘积
	return pow(3, timesof3) * pow(2, timesof2);
}

int main()
{
    
    
	int length = 9;
	int result = MaxProductAfterCutting_Solution(length);
	cout << "此时绳长的最大乘积:" << result << endl;
	return 0;
}

猜你喜欢

转载自blog.csdn.net/m0_46613023/article/details/114900251