Leetcode 343
给定一个正整数 n
,将其拆分为 k
个 正整数 的和( k >= 2
),并使这些整数的乘积最大化。
返回 你可以获得的最大乘积 。
分析:
对于动态规划,可以通过动规五部曲来分析。
1.确定dp数组以及下标含义
dp[i]含义是拆分数字i,可以得到的最大乘积为dp[i],这个很关键
2.确定递推公式
得到乘积可以从1遍历到j,有两种渠道得到dp[i],一个是把i分为j和i-j,j*(i-j);
另一个是j*dp[i-j],相当于拆分(i-j),这里的思想主要就是拆分,将所有的情况都拆分出来。
公式:dp[i] = max(dp[i], max((i - j) * j, dp[i - j] * j));
这里max的原因是可能第一种情况比第二种拆开的情况得到的结果还大,所以要进行比较,并不是拆分就要比不细致拆分数值大。
3.dp初始化
dp[0]和dp[1]初始化没有意义,而dp[2]初始化为1,也就是拆分为1*1。
4.确定遍历顺序
根据递归公式dp[i] = max(dp[i], max((i - j) * j, dp[i - j] * j))
很明显是从前向后遍历,先有dp[i-j]再有dp[i]。
5.打印dp数组\举例推导
举个例子带入公式进行推导,如果得到的结果与预期不符合与可清晰看出
代码:
class Solution {
public:
int integerBreak(int n) {
vector<int> dp(n + 1);
dp[2] = 1;
for (int i = 3; i <= n ; i++) {
for (int j = 1; j <= i / 2; j++) {
dp[i] = max(dp[i], max((i - j) * j, dp[i - j] * j));
}
}
return dp[n];
}
};