给定一个正整数 n
,将其拆分为 k
个 正整数 的和( k >= 2
),并使这些整数的乘积最大化。
返回 你可以获得的最大乘积 。
示例 1:
输入: n = 2
输出: 1
解释: 2 = 1 + 1, 1 × 1 = 1。
示例 2:
输入: n = 10
输出: 36
解释: 10 = 3 + 3 + 4, 3 × 3 × 4 = 36。
提示:
2 <= n <= 58
cpp
class Solution {
public:
int integerBreak(int n) {
// dp[i]: 拆分i,得到最大乘积为dp[i];
// dp[i]:可以拆为dp[j] dp[i-j]
//2、状态转移:dp[i] = max(j*(i-j),j*dp[i-j]);
//分两种情况,拆为j 和 i-j
// 1、i-j不能再拆了,那就是j*(i-j)
// 2、i-j还能再拆,那就是j*dp[i-j]
//也可以理解为 拆两个数 j*(i-j);拆三个即以上j * dp[i-j];
//为什么不是dp[j]呢?我认为,再对j拆分,算是重复了,因为后面dp[i-j]已经拆过了,比方2*dp[4],上一个1*dp[5],对5拆分,可以得到1*1*2*2这个组合,也就是2*dp[4].所以不需要再对j拆分。
vector<int>dp(n+1);
dp[2] = 1;
for(int i = 3;i <= n;i++){
for(int j = 1;j < i;j++){ // j< i-1:j=i-1,在j = 1的时候dp[i-j]已经算过了
//根据常识,数字越集中在一块,乘积越大,和越大。所以也可以j < n/2
dp[i] = max(dp[i],max(j*(i-j),j*dp[i-j]));
}
}
return dp[n];
}
};