343. 求分解整数的乘积最大化Integer Break
Posted AI架构师易筋
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了343. 求分解整数的乘积最大化Integer Break相关的知识,希望对你有一定的参考价值。
343. Integer Break
Given an integer n, break it into the sum of k positive integers, where k >= 2, and maximize the product of those integers.
Return the maximum product you can get.
Example 1:
Input: n = 2
Output: 1
Explanation: 2 = 1 + 1, 1 × 1 = 1.
Example 2:
Input: n = 10
Output: 36
Explanation: 10 = 3 + 3 + 4, 3 × 3 × 4 = 36.
Constraints:
2 <= n <= 58
1. 分左右两部分的乘积,动态规划
注意左右是指当前这个数,也可能是以前的乘积。动态规划子公式为 maxProduct = max(maxProduct, max(l, dp[l]) * max(r, dp[r]))
比如:要找到 8 的最大乘积,请将 8 分解为两项之和(使第一项小于或等于第二项以防止冗余):
1 + 7 --> 1 * 7 = 7
2 + 6 --> 2 * 6 = 12
3 + 5 --> 3 * 5 = 15
4 + 4 --> 4 * 4 = 16
由此看来,最大乘积为 16,但是我们忽略了将这两个术语中的每一个分解为更多术语,并检查所有这些。让我们将 6 分解为 3 + 3
:
2 + 6 = 2 + 3 + 3 --> 2 * 3 * 3 = 18
最终成为正确答案。但另一种方法是重用之前计算的 6 的最大乘积,我们知道它是 9:
2 * (3 * 3) = 2 * max_product_of_6 = 2 * 9 = 18
因此,对于 l <= r
和 l + r = n
的 l 和 r的每个选择,检查 l * r
但还要检查先前计算的最大乘积 dp[l] 和 dp[r] 是否大于 l 和 r。从 n = 1
开始,一直到最后的 n
。将先前计算的值存储在 dp
列表中。
class Solution:
def integerBreak(self, n: int) -> int:
dp = [0, 0]
for m in range(2, n+1):
l = 1
r = m - 1
maxProduct = 0
while l <= r:
maxProduct = max(maxProduct, max(l, dp[l]) * max(r, dp[r]))
l += 1
r -= 1
dp.append(maxProduct)
return dp[-1]
2. table找规律法
我看到很多解决方案都是指 2 和 3 的因数。但是为什么这两个神奇的数字呢?为什么其他因素不起作用?
如果最优产品包含一个因子f >= 4
,那么您可以用因子替换它2
而f-2
,而不会失去最优性,如2*(f-2) = 2f-4 >= f
。因此,您永远不需要大于或等于 4
的因子,这意味着您只需要因子 1
、2
和 3
(而 1 当然是浪费的,您只会将它用于需要它的 n=2 和 n=3) .
其余的我同意,3*3
比 2*2*2
好,所以你永远不会使用 2 超过两次。
显然,e不是整数,因此出于这个问题的目的,我们不能将 n 分成e组。然而,这个结果给了我们直觉,因为 2 < e < 3
,所以只要有可能,n 应该被分成 2 和3。
我们从处理 n 的前几个案例开始,并尝试识别一个模式:
我们可以从这张表中推断出很多东西。首先,一个 DP 解决方案突然出现在我们面前。令 dp[n] 为整数 n 的最大可能乘积。从 n=7
开始,我们注意到 dp[n] = 3*dp[n-3]
。我们得到以下O(n)解:
class Solution:
def integerBreak(self, n: int) -> int:
predp = [0, 0, 1, 2, 4, 6, 9]
if n < 7:
return predp[n]
dp = predp + [0] * (n - 6)
for i in range(7, n+1):
dp[i] = 3 * dp[i-3]
return dp[-1]
(注意:我们包括了 n=0 和 n=1 的无效输入的基本情况,以保持 dp 索引的对齐,避免需要偏移量。)
参考
https://leetcode.com/problems/integer-break/discuss/383679/Python-DP-solution-with-detailed-explanation.-Avoids-confusion-about-factors-of-2-or-3.
https://leetcode.com/problems/integer-break/discuss/80721/Why-factor-2-or-3-The-math-behind-this-problem.
https://leetcode.com/problems/integer-break/discuss/285876/Python-O(1)-one-line-solution-detailed-explanation
以上是关于343. 求分解整数的乘积最大化Integer Break的主要内容,如果未能解决你的问题,请参考以下文章