剑指Offer-剪绳子问题

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

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/jian-sheng-zi-lcof
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

将此题看作完全背包问题,进行动态规划。求长度为n的绳子,剪断为L 和 L - j的两段绳子时,每段绳子的最大乘积。

class Solution {class Solution {
    public int cuttingRope(int n) {
       if(n==2) return 1;
        if(n==3) return 2;
        
        //res存储每段绳子的最大乘积
        int[] res = new int[n+1];
        res[0] = 1;
        for(int i = 1;i<=(n+1)/2;i++){ //遍历物品,即可剪去的绳子长度。 
            for(int j = i;j<=n;j++){  //遍历不同绳子长度,即背包重量
                res[j] = Math.max(res[j],res[j-i]*i);
                //此过程不断更新最大乘积数组,res[j]为原来长度为j的绳子的最大乘积
                //res[j-i]为将j的绳子,减去i
            }
        }
        return res[n];
    }
}


 public static int maxValue3(int n){
        int[] dp = new int[n+1];//长度为n的绳子对应的最大乘积为dp[i]
        dp[0] = 1;
        dp[1] = 1;
        dp[2] = 1;
        //考虑最后一步的情况,长度为i的绳子,可以减去j,可以不剪j,可以减去j后再继续剪
        for(int i = 3;i<=n;i++){ //遍历绳子的长度
            for(int j = 1;j<i;j++){ //遍历可剪去的长度
                dp[i] = Math.max(dp[i],Math.max((i-j)*j,dp[i-j]*j)); //不剪j,剪j后不再继续剪,剪j后继续剪
            }
        }
        return dp[n];
    }

你可能感兴趣的:(java,算法)