每日一题——剑指 Offer 14- I. 剪绳子

112 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第15天,点击查看活动详情


剑指 Offer 14- I. 剪绳子

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

示例 1:

输入: 2
输出: 1
解释: 2 = 1 + 1, 1 × 1 = 1

示例 2:

输入: 10
输出: 36
解释: 10 = 3 + 3 + 4, 3 × 3 × 4 = 36

提示:

  • 2 <= n <= 58

思路

该题目可以很容易使用动态规划来求解,我们只需要依次求出对于每个长度可获得的最大乘积即可.

例如,对于长度为 5 的绳子,我们可以去考虑将其分为长度为 1,长度为 4 两部分,再将这两部分的结果相乘得到其中一个结果,再将其分为长度为 2,长度为 3 两部分,将该两部分的结果相乘得到乘积,依次比较不同的结果,取最大值。每一个长度的结果都需要其子长度的结果相乘得到。

对于每段绳子来说,有分割和不分割两种情况,因为题目要求至少俩段以上,故对于最终所求的长度来说,不可以包含不分割的情况,其他长度可以先考虑不分割的情况,然后再与分割的情况依次比较,取出最优乘积。

题解

class Solution {
    public int cuttingRope(int n) {
        int[] dp = new int[n + 1];
        dp[1] = 1;
        for(int i = 2; i <= n; i++) {
            if(i != n) {
                dp[i] = i;
            }
            for(int j = 1; j <= i; j++) {
                dp[i] = Math.max(dp[i], dp[j] * dp[i - j]);
            }
        }
        return dp[n];
    }
}