题目链接:https://leetcode-cn.com/problems/integer-break/
题意:给定一个正整数 n,将其拆分为至少两个正整数的和,并使这些整数的乘积最大化。 返回你可以获得的最大乘积。
方法: 动态规划,嵌套双重循环,先枚举大整数,然后枚举没有给构成大整数的整数
class Solution {
public:
int integerBreak(int n) {
// 动态规划,存储整数为i时,最大的乘积
vector<int> dp(n+1,0);//定义初始状态
for(int i=2;i<=n;i++)//枚举每一个大整数
{
for(int j=1;j<=i;j++)//枚举每一个构成大整数的整数
{
dp[i] = max(dp[i],max((i-j)*j,dp[i-j]*j));//更新dp值,比较(i-j)*j和dp[i-j]*j的大小是因为当i=2或者3的时候,dp[0]和dp[1]都是0,无法更新
}
}
return dp[n];//返回最后一个dp值
}
};
优化后:将两个循环换个位置,能有效地减少重复的情况,因为会将构成大整数的整数从小到大排列,然后会天然地筛选掉重复的情况。
class Solution {
public:
int integerBreak(int n) {
// 动态规划,存储整数为i时,最大的乘积
vector<int> dp(n+1,0);//定义初始状态
for(int i=1;i<=n;i++)//枚举每一个构成大整数的整数
{
for(int j=i+1;j<=n;j++)//枚举每一个大整数
{
dp[j] = max(dp[j],max((j-i)*i,dp[j-i]*i));//更新dp值
}
}
return dp[n];//返回最后一个dp值
}
};