剑指offer14--剪绳子

链接:https://www.nowcoder.com/questionTerminal/25b04bac36b840ab93f6fd913d1c7247
来源:牛客网
 

编程题

【问题描述】

给你一根长度为n的绳子,请把绳子剪成m段 (m和n都是整数,n>1并且m>1)每段绳子的长度记为k[0],k[1],...,k[m].请问k[0]*k[1]*...*k[m]可能的最大乘积是多少?
【要求】
【数据输入】绳子长度,一个整型数n(n>1)
【数据输出】把绳子剪成m段后, 可能的最大乘积数,也是一个整型数
【样例输入】
绳子的长度n=9
【样例输出】
我们把它剪成长度分别为3,3,3的三段,此时得到的最大乘积是3*3*3=27

思路:

动态规划:

从小到大,10可以由0~5推出来,9可以由0~9/2推出来

这里就是动态方程必须是二维的,时间复杂度为O(n*n)

dp初始化为dp【i】=i。但是如果长度是3,只能返回2

因为题目要求是必须切一下,所以4-----2*2是4     

3------2*1是2,其实在动态规划过程中,必须把dp【3】设置为3

扫描二维码关注公众号,回复: 2644996 查看本文章

贪婪算法:

3的倍数最大,虽然我也不知道怎么推导,但就是这样

然后分为0~4和5以上的两种

5以上的先除以3,剩下的可以依照0~4来做

为什么把4单独提取出来?

因为题目要求是必须切一下,所以4-----2*2是4     

3------2*1是2,其实在动态规划过程中,必须把dp【3】设置为3

而我们贪婪算法中,不需要初始化,但是如果7%3==1.

这时3*3*1不是最大的。就是因为4=2*2>3*1.

ok

调试代码:

#include <iostream>

using namespace std;

int maxResultOfCut(int len)//动态规划
{
	if(len==0)
		return 0;
	if(len==1)
		return 1;
	if (len==2)
		return 1;
	if(len==3)
		return 2;
	int Res=0;
	int *dp=new int [len+1]();
	for(int i=0;i<=len;i++)
		dp[i]=i;//注意这里的初始化与上面返回的区别
	for(int i=4;i<=len;i++)
	{
		for(int j=1;j<=i/2;j++)
		{
			dp[i]=max(dp[i-j]*dp[j],dp[i]);
			//Res=max(dp[i-j]*dp[j],Res);//Res=max(dp[i-j]dp[j],Res);
		}
	}
	Res=dp[len];
	delete dp;
	return Res;
}

int maxResultOfGreedy(int len)
{
	int Res=0;
	if(len<2) return 0;
	if(len==2)	return 1;
	if(len==3)	return 2;
	int timeof3=len/3;
	if(len%3==1)//注意这里必须判断余数为1的情况
		timeof3--;
	return (int)pow((float)3,timeof3)*(int)pow((float)2,(len-timeof3*3)/2);
}

int main()
{
	int n=10;
	//for(int n=0;n<=100;n++)
	//{
		cout<<maxResultOfCut(n)<<endl;
		cout<<maxResultOfGreedy(n)<<endl;
	//}
		return 0;
}

猜你喜欢

转载自blog.csdn.net/m0_37561165/article/details/81306925
今日推荐