整数拆分(难度:中等)
AC代码
class Solution {
public:
int integerBreak(int n) {
//动态规划
//感觉这个题和零钱兑换有点像,只是零钱兑换提供了coin列表
vector <int> dp(n+1,0);
//1、定义子问题
//将原问题求k个整数乘积最大值拆分成
//f(n)=f(k)*(n-k)
//那么求f(n)的最大值的前提是求f(k)已经是最大值
//且k+(n-k)=n
//那如何确保f(k)是最大值呢
//2、子问题递推关系
//n>=2
dp[0]=1;
dp[1]=1;
dp[2]=1;
//3、确定dp数组的计算顺序
//dp[n]=f(k)
int res=INT_MAX;
if(n==2)return dp[2];
for(int i=0;i<n;i++){
//把零钱兑换中的coin列表转换成所有<n的数
//因为k>=2,必须得有两个或两个以上加数,j必须<=n-1
for(int j=1;j<=sqrt(n)+1;j++){
res=dp[i]*j;
//dp[0]*1=dp[1]=1
//dp[0]*2=dp[2]=2
//dp[1]*1=dp[2]=1
//dp[1]*2=dp[3]=2
//...
//dp[2]*1=dp[3]=2
//
//越界就不管了
if(i+j>n)continue;
if(dp[i+j]==0){
dp[i+j]=res;
}
else{
dp[i+j]=max(res,dp[i+j]);
}
}
}
return dp[n];
}
};