14:剪绳子

f(n) 为把长度为 n 的一段绳子剪成若干段后(不能不剪),各段长度乘积的最大值,求 f(n)

在剪第一刀的时候,可以将绳子分为 in-i 的两段,遍历所有情况,找出 max(f(i)*f(n-i)) ,这个值就是f(n) 而最优解f(n) 又依赖于子问题 f(i)f(n-i) 的最优解,子问题之间又包括大量的重复部分,所以要从下到上解决这个问题,保存子问题的解,为上层问题提供解的基础。

当绳子的长度为2时,只能剪成长度为1, 1的两段,所以f(2) = 1

当绳子的长度为3时,能剪成1, 1, 11, 2 选后者, 则f(3) = 2

当绳子的长度大于3时,因为2>f(2), 3>f(3),故可以剪成最小长度为2, 3绳子,不继续剪

由于是自底向上的求解,并且在每个长度下都求出最优解,故需要两层循环,时间复杂度O(n^2)

public static int interBreak(int length) {
    if (length < 2) return 0;
    if (length == 2) return 1;
    if (length == 3) return 2;

    int[] products = new int[length + 1];
    products[0] = 0;
    products[1] = 1;
    products[2] = 2;
    products[3] = 3;

    for (int i = 4; i <= length; i++) {
        products[i] = 0;  //多余的
        for (int j = 1; j <= i / 2; j++) {
            int k = products[j] * products[i - j];
            products[i] = products[i] < k ? k : products[i];
        }
    }

    return products[length];
}

猜你喜欢

转载自blog.csdn.net/weixin_41889284/article/details/89312042