每日一题 - day15 - 15. 剪绳子 - 动态规划 - Java实现

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/jun8148/article/details/86251478

15. 剪绳子 - 动态规划

问题描述

给你一根长度为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.

分析

1、比如有一段长度为n的绳子,我们现在要剪第一刀,我可以选择下第一刀的地方有1 ~ n-1这些地方;比如长度为10的绳子,我第一刀可以在1~9这些地方下刀,共9种方式。

2、第一刀下去后,绳子分成两部分,假设在i处下刀,绳子两部分就分别为:[0 ~ i]与[i ~ n],长度分为表示为i与n-i;那么找出第一刀最合适的位置,其实就是找i在哪下刀,可以使得[0 ~ i]与[i ~ n]的乘积最大,函数表示为:

f(n) = max(f(i) * f{n-i))

3、那么如何判断i处切最大呢?这个时候,我们就要知道,[0 ~ i]这个长度的绳子,任意方式切,最大的乘积是多少;假如说,当我们要切一个长度为10的绳子:

切成1和9与4和6,两种方式,哪个乘积更大?

回答:不光要考虑第一刀后两个绳子的大小,还要考虑到,9、4、6这三种情况下,因为第一刀切出的绳子长度是否可以再切第二刀,使它有更大的乘积,比如将9再切成333,6切成4*2,哪个更大?

这种情况下,我们可以发现,无论再怎么切,一定是越切越短,那么我们是否可以将小于给定长度的绳子的每一个长度的最大乘积都求出来?

即:长度为10的绳子,我们就计算出:长度1~9这9种长度的绳子,每种长度的最大乘积是多少。

要求长度9的绳子的最大乘积,我们要知道1 ~ 8各个长度的最大乘积,要知道长度8的最大乘积,就要知道1 ~ 7长度的各个最大乘积,以此类推。

代码

public static int maxProductAfterCutting_solution(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;
    int max = 0;
    for (int i = 4; i <= length; i++) {
        max = 0;
        for (int j = 1; j <= i / 2; j++) {
            int product = products[j] * products[i - j];
            if (max < product) {
                max = product;
            }
            products[i] = max;
        }
    }
    return products[length];
}

猜你喜欢

转载自blog.csdn.net/jun8148/article/details/86251478