问题描述:
解法一:数学(优先推荐)
目标就是将长度分解为尽可能多的x的乘积,那么问题就转化为求f(x)=x的(x/n)次方的最大值。根据数学计算与证明得出x的值为3,也就是说要保证分解的结果有尽可能多的3。
当n=2时,结果为1.
当n=3时,结果为2.
当n>3时,我们先考虑最多有多少个3.
令a=n/3; b=n%3.
当b=0时,结果当然是3的n次方。
当b=1时,因为3 * 1<2 * 2,所以将末尾的3+1改成2+2,那么结果就是(a-1个3)* 2* 2。
当b=2时,结果就是(a个3)*2.
代码如下
class Solution {
public int cuttingRope(int n) {
int a=n/3;
int b=n%3;
if(n<=3){
return n-1;
}
if(b==0){
return (int)Math.pow(3,a);
}
else if(b==1){
return (int)(Math.pow(3,a-1)*4);
}
else{
return (int)(Math.pow(3,a)*2);
}
}
}
解法二:动态规划
动态规划也很容易理解。
一个数j可以被拆分成两段i(i<j)和j-i。那么我们假设i是固定的,那么j无非就两种情况,一种是不可拆分,一种是也可以拆分成两段。拆分成两段的逻辑就又回到了我们一开始的逻辑了。那么整个数的拆分的积就有如下两种情况。
i*(j-i);
i*a[j-i];
那么i就是从1开始到j-1,j就是从2开始到n。
代码如下
class Solution {
public int cuttingRope(int n) {
int[] a=new int[n+1];
a[0]=a[1]=0;
int max=0;
for(int j=2;j<=n;j++){
for(int i=1;i<j;i++){
max=Math.max(max,Math.max(i*(j-i),i*a[j-i]));
}
a[j]=max;
}
return a[n];
}
}