题目描述

给你一根长度为n的绳子,请把绳子剪成整数长的m段(m、n都是整数,n>1并且m>1),每段绳子的长度记为k[0],k[1],…,k[m]。请问k[0]xk[1]x…xk[m]可能的最大乘积是多少?

例如,当绳子的长度是8时,我们把它剪成长度分别为2、3、3的三段,此时得到的最大乘积是18。

题目分析

要让最大乘积最大,则当n > 5时,使用尽可能多的3。

贪心算法

  • 数学分析

$$ \begin{matrix} if\space x\%3 &numOf2 &numOf3\newline \space\space 0 & 0 & x/3\newline \space\space 1 & 2 & x/3-1\newline \space\space 2 & 1& x/3\newline \end{matrix} $$

实现代码

public int cutRope2(int target) {
    if (target < 2)
        return 0;
    if (target == 2)
        return 1;
    if (target == 3)
        return 2;

    int numOf3 = target / 3;
    int numOf2 = 0;
    if (target % 3 == 1) {
        numOf3--;
        numOf2 = 2;
    }
    if(target % 3 == 2){
        numOf2 = 1;
    }
    //  int numOf2 = (target -  numOf3*3) / 2;
    return (int) (Math.pow(2, numOf2) * Math.pow(3, numOf3));
}

递推算法

数学分析

$$ f(n)= \begin{cases} f(n-3), & \text{if $n$ > 6}\newline [1,2,4,6],& \text{if n = 2,3,4,5} \end{cases} $$

实现代码

public int cutRope(int target) {
        int n = 60;
        int[] dp = new int[n+1];
        dp[2] = 1;dp[3] = 2;
        dp[4] = 4;dp[5] = 6;
        for(int i = 6;i <= 60;i++){
            dp[i] = 3 * dp[i-3];
        }
        return dp[target];
}

递归算法

数学分析

$$ f(n)= \begin{cases} f(n-3), & \text{if $n$ > 6}\newline [1,2,4,6],& \text{if n = 2,3,4,5} \end{cases} $$

实现代码

public class Solution {
public int cutRope(int target) {
            if (target == 2)
                return 1;
            if (target == 3)
                return 2;
            if(target == 4)
                return 4;
            if(target == 5)
                return 6;
            return cutRope(target - 3) * 3;
    }
}