描述

剪绳子

把一根绳子剪成多段(>1),并使得所得到每段绳子的长度之积最大。

例子
Input:
	n(绳长)
Output:
	

思路

方法一: 贪婪算法

使得所得到的绳子中3的数量最多,1的数量最少(没有)

方法二: 动态规划

定义 f(n) : 最大乘积,f(n) = max{f(i)*f(n-i)}

代码
public class Demo014 {

    // 贪婪算法
    public static int maxLength(int n) {
        if (n < 2) {
            return 0;
        } else if (n == 2) {
            return 1;
        } else if (n == 3) {
            return 2;
        } else {
            if (n%3==1){
                return (int) Math.pow(3, n/3-1)*4;
            } else if(n%3==0) {
                return (int) Math.pow(3, n/3);
            } else {
                return (int) Math.pow(3, n/3)*2;
            }
        }
    }

    // 动态规划
    // 定义 f(n) : 最大乘积
    // f(n) = max{f(i)*f(n-i)}
    public static int dp(int n) {
        if (n < 2) {
            return 0;
        } else if (n == 2) {
            return 1;
        } else if (n == 3) {
            return 2;
        } else {
            int [] dp = new int [n+1];
            // 分割绳子长度1,2,3,具体动态规划从4开始计算
            // dp[i]数组,绳子长度为i时,乘积最大值
            dp[1] = 1;
            dp[2] = 2;
            dp[3] = 3;
            int max = 0;
            // 存放中间值
            int temp = 0;
            for (int i = 4; i <= n; i++) {
                max = 0;
                // i/2 对于绳子i的切分,j*(i-j) 与 (i-j)*j结果一样
                for (int j = 1; j <= i / 2; j++) {
                    temp = dp[j] * dp[i-j];
                    if (temp > max) {
                        max = temp;
                    }
                }
                dp[i] = max;
            }
            return dp[n];
        }
    }

    public static void main(String[] args) {
        System.out.println(maxLength(11));
        System.out.println(dp(11));
    }
}