题目内容
给你一根长度为 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:
1 | 输入: 2 |
示例 2:
1 | 输入: 10 |
提示:
1 | 2 <= n <= 58 |
解法一:动态规划
思路:
对于的长度为n的绳子,当 n ≥ 2 时,可以剪成至少两个绳子。令 k 是剪出的第一段绳子,则剩下的部分是 n−k,n−k 可以不继续剪,或者继续剪成至少两段绳子
算法:
dp[i] 表示将长度为 i 的绳子剪成至少两段绳子之后,这些绳子长度的最大乘积
当 i ≥ 2 时,假设对长度为 i 绳子剪出的第一段绳子长度是 j(1≤j<i),则有以下两种方案:
- 将 i 剪成 j 和 i-j 长度的绳子,且 i−j 不再继续剪,此时的乘积是 j×(i−j) ;
- 将 i 剪成 j 和 i−j 长度的绳子,且 i−j 继续剪成多段长度的绳子,此时的乘积是 j×dp[i−j] 。
因此,当 j 固定时,有 dp[i]=max(j×(i−j),j×dp[i−j])。由于 j 的取值范围是 1 到 i ,需要遍历所有的 j 得到dp[i]的
1 | class Solution { |
1 | 执行用时: |
解法二:贪心算法
思路:
核心思路是:尽可能把绳子分成 长度为3的小段,这样乘积最大。
算法
- 如果 n === 4,返回4
- 如果 n > 4,分成尽可能多的长度为3的小段,每次循环长度n减去3,乘积res乘以3;最后返回时乘以小于等于4的最后一小段
1 | class Solution { |
1 | 执行用时: |