给定一个正整数 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
解题思路:
动态规划五步曲
- 确定dp数组(dp table)以及下标的含义
- 确定递推公式
- dp数组如何初始化
- 确定遍历顺序
- 举例推导dp数组
1.确定dp数组以及下标的含义
我们的目标是求分解数字的成绩的最大和,所以,dp[i]存储的应该是数字i拆分的数字成绩的最大值
2.确定递推公式
对于dp[i],即分解数字i得到最大乘积,如果分为两个数,用j从1开始遍历,乘积为(i-j)*j
或者拆分为多个数,这里就要想到用dp[i-j]*j,dp[i-j]就是将一个数拆分为两个及两个以上
求出这两个成绩之前的最大值,即max(dp[i-j]*j,(i-j)*j)
dp[i] = max(dp[i],max(dp[i-j]*j,(i-j)*j)
3.dp数组的初始化
这里的初始化,dp[0]为0,dp[1]也为0,直到dp[2]为1 * 1 = 1
4.确定遍历顺序
如果i < 3,其实就没有遍历的必要了,所以i从3开始遍历,
j则从1开始,到i-1,如果是到i,则会出现i-j为1,任何正数乘1都是1,所以没有遍历的必要
5.举例推导dp数组
for(int i = 3;i <= n;i++) { for(int j = 1;j < i - 1;i++) { dp[i] = max(dp[i],max((i-j)*j),dp[i-j]*j); } }
给出LeetCode的代码
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 - 1;j++) { dp[i] = max(dp[i],max(j*(i-j),j*dp[i-j])); } } return dp[n]; } };
标签:遍历,数字,int,拆分,数组,动态,dp,乘积 From: https://www.cnblogs.com/polang19/p/17114975.html