题目链接
参考详解
首先先用贪心算法。
当n>=5时,我们要尽可能的多剪长度为3的绳子.
证明此结论可看:结论证明
class Solution {
public:
int cuttingRope(int n) {
if(n==2)return 1;
if(n==3)return 2;
if(n==4)return 4;//n=1,2,3,4单独讨论
int a=n/3,b=n%3;
if(b==0)return pow(3,a);//当余数为0时,直接求3的a次方
else if(b==1)return pow(3,a-1)*4;
//当余数为1时,直接求3的a-1次方,剩下的1和剩下的3相加变为4。不加的话,1就没有对乘积结果有贡献。
else return pow(3,a)*2;
//当余数为2时,有两种情况。(1)将两个3变为4.(2)直接乘2。自己在纸上举例证明会发现,直接乘2较大。
}
};
再用动态规划方法:
定义函数:f(n)为长度是i的绳子剪段后各段长度成绩的最大值。
随便剪一刀有 n-1 种可能,每次前半段的长度i分别为 1,2,3,…,n-1。所以可得到递推公式:f(n)=max(f(i)*f(n-i))(0<i<n)。
可以采取从下往上的顺序计算,减少大量不必要的重复计算,即先算f(2)、f(3),再算f(4)、f(5),一直到f(n)。
class Solution {
public:
int cuttingRope(int n) {
if(n==2)return 1;
if(n==3)return 2;
int *product=new int[n+1];
product[0]=0;product[1]=1;product[2]=2;product[3]=3;//当n>=4时
int max=0;
for(int i=4;i<=n;i++)
{
max=0;
for(int j=1;j<=i/2;j++)
{
if(max < product[j] * product[i-j])
{
max=product[j] * product[i-j];
}
product[i]=max;
}
}
max=product[n];
return max;
}
};