题目
给定一个正整数 n,将其拆分为至少两个正整数的和,并使这些整数的乘积最大化。 返回你可以获得的最大乘积。
示例 1:
输入: 2
输出: 1
解释: 2 = 1 + 1, 1 × 1 = 1。
示例 2:
输入: 10
输出: 36
解释: 10 = 3 + 3 + 4, 3 × 3 × 4 = 36。
说明: 你可以假设 n 不小于 2 且不大于 58。
动态规划四步走
1. 定义状态
2. 初始状态
3. 状态转移方程
4. 从dp[]中获取结果
具体到题目
定义状态
定义dp[i]为数字i拆分的最大乘积
初始状态
dp[0] = 0;
dp[1] = 0;
状态转移方程
以数字5为例,可以至少可以分解成1+4,因此对于数字n,至少可以分解得到的乘积为n-1;
遍历2到n/2向上取整,每个分解的数取指针j和dp[j]的最大值,另一部分就是n-j或者dp[n-j]的最大值,此时的乘积就是取j的乘积。
let res= n-1
for(let j=2;j<= Math.ceil(n/2),j++)
cur = max(j,dp[j])*max(n-j,dp[n-j])
res = cur > res ? cur: res;
dp[n] = res
完整代码
var integerBreak = function (n) {
if (typeof n !== 'number' || n < 2) {
return;
}
const dp = new Array(n + 1).fill(0);
dp[0] = 0;
dp[1] = 0;
for (let i = 2; i <= n; i++) {
let res = i - 1;
for (let j = 1; j <= Math.ceil(i / 2); j++) {
const k = i - j;
const cur = Math.max(j, dp[j]) * Math.max(k, dp[k]);
if (cur > res) {
res = cur;
}
}
dp[i] = res;
}
console.log(dp);
return dp[n];
};
总结
数学找规律题,自底向上分析就可以得到复用关系