Given a positive integer n, break it into the sum of at least two positive integers and maximize the product of those integers. Return the maximum product you can get.
Example 1:
Input: 2
Output: 1
Explanation: 2 = 1 + 1, 1 × 1 = 1.
Example 2:
Input: 10
Output: 36
Explanation: 10 = 3 + 3 + 4, 3 × 3 × 4 = 36.
给一个正整数n,把n至少分解成2个整数,使分解的整数乘积最大
思路:
(1)dp
比如10分解成2个整数的时候,可以分解成以下组合
1 * 9, 2* 8, 3 * 7, 4 * 6, 5 * 5,6* 4, 7 * 3, 8 * 2, 9 * 1
从这中间先选最大的
然后比如3 * 7, 7还可以进一步分解成[1 * 6, 2 * 5, 3 * 4, 4 * 3, 5 * 2, 6 * 1]
7分解的整数乘积的最大值在从1~10的过程中已经计算过了,再用到时只需要调用dp
所以dp[i] = max(两个数的积(比如3 * 7), 进一步分解的最大值(比如:3 * dp[7]))
这个方法在time complexity上,在目前的时间点上faster than 52.24%
//1ms
public int integerBreak(int n) {
if (n <= 3) {
return (n - 1);
}
int[] dp = new int[n + 1];
dp[2] = 1;
dp[3] = 2;
for (int i = 4; i <= n; i++) {
for (int j = 1; j <= i; j++) {
//每个i对应很多j,要把dp[i]也放入max的比较中,防止最大值被淹没
//可以是j*(i-j),也可以是(i-j)进一步拆分的数字的乘积*i
dp[i] = Math.max(dp[i], j * (i - j));
dp[i] = Math.max(dp[i], j * dp[i - j]);
}
}
return dp[n];
}
(2) 数学方法
参照https://blog.youkuaiyun.com/qq_17550379/article/details/82811007
以3作基底的乘积最大,推导
我们将n拆分成n/x个数值为x的整数,那么这些整数的乘积就是xn/xx^{n/x}xn/x, 这个乘积对x求导
y=xn/xy = x^{n/x}y=xn/x
lny=(n/x)lnxlny = (n/x)lnxlny=(n/x)lnx
y′/y=−(n/x2)lnx+(n/x2)y'/y = -(n/x^{2})lnx + (n/x^{2})y′/y=−(n/x2)lnx+(n/x2)
y′=n(1−lnx)x(n/x−2)y' = n(1-lnx)x^{(n/x - 2)}y′=n(1−lnx)x(n/x−2)
所以在x=e的时候乘积最大,x=2或3
而2∗2∗2<3∗32*2*2 < 3*32∗2∗2<3∗3
所以想要乘积最大,那么一定要将3作为基底,并且<=4的余数不再进行拆分。
此方法在当前时间点上,time complexity: faster than 100%
//0ms
public int integerBreak(int n) {
if (n <= 3) {
return (n - 1);
}
int result = 1;
//<=4的余数不再拆分
while (n > 4) {
result *= 3;
n -= 3;
}
result *= n;
return result;
}