Bootstrap

[Leecode] 剪绳子问题

问题描述:
在这里插入图片描述
解法一:数学(优先推荐)

目标就是将长度分解为尽可能多的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];
    }
    
}
;