题目描述

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

输入描述:

输入一个数n,意义见题面。(2 <= n <= 60)

输出描述:

输出答案。

输入

8

输出

18
思路:将一个正整数拆分为若干个正整数的和,使得这些正整数的乘积最大,那么
1.拆的个数尽可能多,但不要拆成1,
2.且拆成的数不要大于4(因为5<2*3,6<3*3,...),
3.并且拆成的数2的个数不要超过2个(因为2*2*2<3*3)
class Solution {
public:
    int cutRope(int number) {
        if(number == 2)
            return 1;
        if(number==3)
            return 2;
        int rem = number % 3;
        int quo = number / 3;
        
        if(rem == 0){
            return pow(3,quo);
        }else if(rem == 1){
            return pow(3,quo-1)*2*2;
        }else{
            return pow(3,quo)*2;
        }
    }
};

 

 动态规划法:

 dp[i]表示绳长为i时对应的最大值

那么dp[i] =max {不切话乘积值,dp[j]*dp[i-j]}(1 <= j <= i/2)

public int cutRope(int target) {
        if(target==2)
            return 1;
        if(target == 3)
            return 2;
        int[] dp = new int[target+1];
        int max = 0;
        dp[1] = 1;
        dp[2] = 2;
        dp[3] = 3;
        for(int i = 4;i<=target;i++){
            for(int j=1;j<=i/2;j++){
                max = Math.max(max,dp[j]*dp[i-j]);
            }
            dp[i] = max;
        }
        
        return dp[target];
    }

 讨论区大神解法:

public int cutRope(int target) {
//定义最大值数组,题目要求最大长度是 60
        int[] dp = new int[62];// 0 - 61
        //给定初始值
        dp[1] = 1;
        //对于 2 -> target - 1 打表 做最优分法(不一定是二分,可以一分)
        for (int i = 2; i <= target; i++) {
            // max 初始化为 一分的结果(本身)
            int max = i;
            // 对于最少二分做解
            for (int j = 1; j <= i / 2; j++) {
                max = Math.max(max, dp[j] * dp[i - j]);
            }
            // 写入结果
            dp[i] = max;
        }
        // 定义target的初始值
        
        return dp[target];
    }

 

 

 

 
posted on 2020-09-01 21:44  曹婷婷  阅读(170)  评论(0编辑  收藏  举报