【动态规划】【打卡93天】《剑指Offer》2刷:减绳子

1、题目描述

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

2、算法分析

 题目中说长度为n的绳子剪成m段。且n>1 m>1。

定义dp数组,dp[i]表示长度为i的绳子剪成m端后长度的最大乘积(m>1)。

dp[2] = 1;因为2 = 1+1,最大乘机为1

target = n的时候,首先对绳子剪长度为j的一段,其中取值范围为 2 <= j < i。

//转移方程如下
dp[i] = Math.max(dp[i],Math.max(j*(i-j),j*dp[i-j]));
//Math.max(j*(i-j),j*dp[i-j]是由于减去第一段长度为j的绳子后,可以继续剪也可以不剪
//Math.max(dp[i],Math.max(j*(i-j),j*dp[i-j]))是当j不同时,求出最大的dp[i]

//现在已经求出每个长度i对应的最大乘积,返回dp[n]

3、代码实现

class Solution {
    public int cuttingRope(int n) {
        //定义dp数组,dp[i]表示长度为i的绳子剪成m端后长度的最大乘积(m>1)
        int dp[] = new int[n+1];
        //初始化
        dp[2] = 1;
        //目标:求出dp[n]
        //dp[2]已知,从dp[3]开始求,直到求出dp[n]
        for(int i = 3;i <= n;i++){
            //首先对绳子剪长度为j的一段,其中取值范围为 2 <= j < i
            for(int j = 2;j < i;j++){
                
                //转移方程如下
                dp[i] = Math.max(dp[i],Math.max(j*(i-j),j*dp[i-j]));
                //Math.max(j*(i-j),j*dp[i-j]是由于减去第一段长度为j的绳子后,可以继续剪也可以不剪
                //Math.max(dp[i],Math.max(j*(i-j),j*dp[i-j]))是当j不同时,求出最大的dp[i]
            }
        }
        //现在已经求出每个长度i对应的最大乘积,返回dp[n]
        return dp[n];
    }
}

猜你喜欢

转载自blog.csdn.net/Sunshineoe/article/details/121444143