1.动态规划
首先当n=2时,返回1,n==3返回2
对于其他情况,设dp[i]表示对于正整数i,存在的最大乘积
首先初始化dp[0]=1;
dp[1]=1
dp[2]=2;
dp[3]=3,
当i>3时,遍历1--i-1,dp[i]=max(dp[i],dp[i-j]*j);
代码如下:
class Solution {
public:
int integerBreak(int n) {
if(n==2)
return 1;
if(n==3)
return 2;
vector<int> dp(n+1,0);//dp[i]表示长度为i的最大乘积
//需要初始化前几个数的初值
dp[0]=1;
dp[1]=1;
dp[2]=2;
dp[3]=3;
for(int i=4;i<=n;i++)
for(int j=1;j<i;j++)
dp[i]=max(dp[i],dp[i-j]*j);
return dp[n];
}
};
2.动态规划+数学方法
通过观察,可以发现dp[i]=3*max(i-3,dp[i-3]);
代码如下:
class Solution {
public:
int integerBreak(int n) {
if(n==2)
return 1;
if(n==3)
return 2;
vector<int> dp(n+1,0);//dp[i]表示长度为i的最大乘积
//需要初始化前几个数的初值
dp[0]=0;
dp[1]=0;
dp[2]=1;
dp[3]=2;
dp[4]=4;
for(int i=5;i<=n;i++)
dp[i]=3*max(i-3,dp[i-3]);
return dp[n];
}
};
3.数学方法
当分解的数中含有尽量多的3时,乘积最大,这里需要注意一个情况就是:
余数只有1,和2
如果n%3==1,即余数为1时,则乘1对结果不会有影响,需要回退一下,
如果n%3==2,则直接计算即可
代码如下:
class Solution {
public:
int integerBreak(int n) {
if(n==2)
return 1;
if(n==3)
return 2;
int k=n/3;
int num=pow(3,k);
if(n%3==1)
num=(num/3)*4;
else if(n%3==2)
num=num*2;
return num;
}
};