剪绳子问题 贪心和动态规划

题目描述:

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

最优解问题,可以考虑贪心算法或动态规划:

贪心算法:是否满足贪心算法的特征?

⑴最优子结构性质:当一个问题的最优解包含其子最优解时,称为最优子结构性质(能从局部扩展到最优)。

⑵贪心选择性质:问题的整体最优解可以由局部一系列的最优解的选择来得到。

具体到实际问题中需要用数学方法证明能够通过贪心求得最优解。

思路:

⑾通过前五六个数可以发现尽量多的3尽量少的2可以求得最大的解,而4出现了不同;

⑿4出现不同的原因是出现了1,所以考虑把3和1结合成为两个2,求得了最大解;

⒀可以发现当n>5时,3(n-1)>=2(n-2),所以把⑾、⑿的想法推广。

代码实现:

#include
using namespace std;
int cutRope(int number){				 
	if(number==2)						//长度为2时剪一段 1*1 
		return 1;
	if(number==3)						//长度为3时剪一段1*2 
		return 3;
	int Rope3=number/3;					//长度大于3后,大于3的数都可以分解为1,2,3的和,又因为3(n-3)>=2(n-2),所以将其分解为尽量多的3和尽量少的2。4是特例所以有了下面的判断 
	if((number-Rope3*3)==1){			//最后剩下的1需和一个3进行重组为两个2 
		Rope3--;
	}
	int Rope2=(number-Rope3*3)/2;
	return pow(3,Rope3)*pow(2,Rope2);	//用pow()函数进行计算 
}
int main(){
	int n;
	cin>>n;
	cout<

时间复杂为O(1)。

动态规划:求一个问题的最优解,且这个问题能分成若干个子问题,整体的最优解也依赖于子问题的最优解。

特点:从上往下分析,从下往上实现。

代码放下,思路还未完全理解。

int DcutRope(int n){
	if(n==2)						
		return 1;
	if(n==3)						
		return 3;
	int *products=new int[n+1];
	products[0]=0;
	products[1]=1;
	products[2]=2;
	products[3]=3;
	
	int max=0;
	for(int i=4;i<=n;i++){
		max=0;
		for(int j=1;j<=i/2;j++){
			int product=products[j]*products[i-j];
			if(max

 

你可能感兴趣的:(剪绳子问题 贪心和动态规划)