题目描述
给定一个正整数 n,将其拆分为至少两个正整数的和,并使这些整数的乘积最大化。 返回你可以获得的最大乘积。
示例1:
输入: 2
输出: 1
解释: 2 = 1 + 1, 1 × 1 = 1。
示例2:
输入: 10
输出: 36
解释: 10 = 3 + 3 + 4, 3 × 3 × 4 = 36。
思想
- 2 => 1 + 1
- 3 => 2 + 1
- 4 => 2 + 2
- 5 => 2 + 3
- 6 => 3 + 3
- 7 => 3 + 4
- 8 => 3 + 3 + 2
- 9 => 3 + 3 + 3
- 10 => 3 + 3 + 2 + 2
观察 10 跟 8, 还有 7 的关系, 观察9 跟 7 还有 6 的关系, 我这里直接用dp表示
dp[10] = max(dp[8] * 2, dp[7] * 3)
, =>max(3 * 3 * 3 * 2, 3 * 4 * 3)
dp[9] = max(dp[7] * 2, dp[6] * 3)
, =>max(3 * 4 * 2, 3 * 3 * 3)
注意:但你会发现 从dp[6] 往上就不符合上面的方法了,
dp[6] = max(dp[4] * 2, dp[3] * 3)
所以我直接做了暴力破解!直接赋值
代码
/**
* @param {number} n
* @return {number}
*/
var integerBreak = function(n) {
let dp = Array(n + 1).fill(1);
dp[3] = 2;
dp[4] = 4;
dp[5] = 6
dp[6] = 9
for(let i = 7; i <= n; i++) {
dp[i] = Math.max(dp[i - 3] * 3, dp[i - 2] * 2);
}
return dp[n]
};
官方题解
dp[i]=max(2×(i−2),2×dp[i−2],3×(i−3),3×dp[i−3])
class Solution {
public:
int integerBreak(int n) {
if (n < 4) {
return n - 1;
}
vector dp(n + 1);
dp[2] = 1;
for (int i = 3; i <= n; i++) {
dp[i] = max(max(2 * (i - 2), 2 * dp[i - 2]), max(3 * (i - 3), 3 * dp[i - 3]));
}
return dp[n];
}
};