《剑指Offer》面试题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。

测试用例:

  1. 功能测试(绳子的初始长度大于5)
  2. 边界值测试(绳子的初始长度分别为0,1,2,3,4)

本题考点:

  1. 考查应聘者的抽象建模能力。应聘者需要把一个具体的场景抽象成一个能够用动态规划或者贪婪算法解决的模型。
  2. 考查应聘者对动态规划和贪婪算法的理解。能够灵活运用动态规划解决问题的关键是具备从上到下分析问题、从下到上解决问题的能力,而灵活运用贪婪算法则需要扎实的数据基本功。

源代码:

#include <cmath>

//动态规划
int maxProductAfterCuttig_solution(int length)
{
	if (length < 2)
		return 0;
	if (length == 2)
		return 1;
	if (length == 3)
		return 2;

	int *product = new int[length + 1];
	product[0] = 0;
	product[1] = 1;
	product[2] = 2;
	product[3] = 3;

    //这里的是错误的,我误以为
    //当n大于3最大值f(n) = f(n/2)*f(n - n/2)
	/*int max = 0;
	int midPos = 0;
	int	upPos = 0;

	for (int i = 4; i <= length; i++)
	{
		max = 0;
		midPos = i / 2;
		upPos = i - midPos;
		product[i] = product[midPos] * product[upPos];
	}*/
    
    //正确的方法如下,最大值f(n) = max(f(i) *f(n-i))
	int max = 0;

	for (int i = 4; i <= length; i++)
	{
		max = 0;
		int tempValue = 0;
		for (int j = 0; j <= i / 2; ++j)
		{
			tempValue = product[j] * product[i - j];
			if (max < tempValue)
				max = tempValue;

			product[i] = max;
		}
	}

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

//贪婪算法
int maxProductAfterCutting_solution2(int length)
{
	if (length < 2)
		return 0;
	if (length == 2)
		return 1;
	if (length == 3)
		return 2;

	//尽可能多地剪去长度为3的绳子段
	int timesOf3 = length / 3;
	if (length - timesOf3 * 3 == 1)
		timesOf3 -= 1;

	int timesOf2 = (length - timesOf3 * 3) / 2;
	return pow(3, timesOf3) *pow(2, timesOf2);
}

参考代码:https://github.com/zhedahht/CodingInterviewChinese2/tree/master/14_CuttingRope
自己代码:https://github.com/quinta2019/Offer/tree/master/14_Q_CuttingRope

评论 16
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值