题目描述:
给定一个正整数 n ,将其拆分为 k 个 正整数 的和( k >= 2 ),并使这些整数的乘积最大化。
返回 你可以获得的最大乘积 。
思考
-
dp[i]:表示将i拆分之后获得的最大的乘积
-
递推公式: 可以想 dp[i]最⼤乘积是怎么得到的呢?
其实可以从1遍历j,然后有两种渠道得到dp[i]:
-
j * (i - j) 直接相乘 (拆分为两个数);
-
j * dp[i - j],相当于是拆分(i - j),j怎么就不拆分呢? j是从1开始遍历,拆分j的情况,在遍历j的过程中其实都计算过了。(拆分为3个或3个以上的数字)
故可以得到递推公式:dp[i]=max((i - j) * j, dp[i - j] * j)
-
-
初始化:i=0,i=1时,无法进行拆分,故拆分之后不存在最大乘积,将dp[0],dp[1]初始化为0;当i=2时,可以拆分为1+1,故dp[2]=1.
-
遍历顺序:
- dp[i] 是依靠 dp[i - j]的状态,所以遍历i⼀定是从前向后遍历,先有dp[i - j]再有dp[i];
- 枚举j的时候,是从1开始的。i是从3开始,这样dp[i - j]就是dp[2]正好可以通过我们初始化的数值求出来。
-
打印dp数组。
代码
var integerBreak = function(n) {
var dp=[];
//初始化
dp[0]=0;
dp[1]=0;
dp[2]=1;
for(let i=3;i<=n;i++){
let temp=0;//存储每次拆分的乘积
// 对i进行拆分,从j=1开始,到i-1结束
for(let j=1;j<i;j++){
dp[i]=Math.max(temp,Math.max(j*(i-j),j*dp[i-j]));
temp=dp[i];
}
}
return dp[n];
};
结果