题目:
给定一个正整数 n,将其拆分为至少两个正整数的和,并使这些整数的乘积最大化。 返回你可以获得的最大乘积。
题解思路:
方法一:数学分割法
思路:
1.判断数字n是否小于等于3,若是,返回n-1;否则把整数n除以3整数部分为a,余数部分为b,在利用指数部分计算。
3.如果b为0,则数字最大为pow(3,a);b为1,最大数字为pow(3,a-1)*4;b为2时,最大数字为pow(3,a)*2.
函数代码:
class Solution {
public:
int integerBreak(int n) {
if(n<=3)
{
return n-1;
}
int a=n/3,b=n%3;
if(b==1)
{
return pow(3,a-1)*4;
}
else if(b==2)
{
return pow(3,a)*2;
}
else
{
return pow(3,a);
}
}
};
方法二:动态规划
思路:
1.当n<=3时,返回的是n-1;初始化dp,dp[1]=0;
2.取2<=i<=n,1<=j<i; 数字i可以被分分解几段数字进行乘积当i分割为j*(i-j),此时不能在分割;还有就是数字i分割为j*dp[i-j];
3.dp[i]的每个时候确保是最大值,所以设定一个当下变量最大值curmax记录dp[i],curmax=max(curmax,dp[i-j]j);curmax=max(curmax,j(i-j));
也可也一次性求出curmax,curmax=max(curmax,max(j(i-j),j*dp[i-j]));*
最后返回dp[n];
函数代码:
class Solution {
public:
int integerBreak(int n) {
if(n<=3)
{
return n-1;
}
vector<int>dp(n+1,0);
dp[0]=dp[1]=0;
for(int i=2;i<n+1;i++)
{
int curmax=0;
for(int j=1;j<i;j++)
{
curmax=max(curmax,max(j*(i-j),j*dp[i-j]));
}
dp[i]=curmax;
}
return dp[n];
}
};
方法三:动态规划+数学分割法
当i>=3时,dp[i]=max(max(2dp[i-2],2(i-2)),max(3dp[i-3],3(i-3)));
函数代码:
class Solution {
public:
int integerBreak(int n) {
if(n<=3)
{
return n-1;
}
vector<int>dp(n+1,0);
dp[0]=dp[1]=0;
dp[2]=1;
for(int i=3;i<n+1;i++)
{
dp[i]=max(max(2*dp[i-2],2*(i-2)),max(3*dp[i-3],3*(i-3)));
}
return dp[n];
}
};