题干:给定一个正整数 n
,将其拆分为 k
个 正整数 的和( k >= 2
),并使这些整数的乘积最大化。返回 你可以获得的最大乘积 。
示例:
输入:n = 10
输出:36
解释: 10 = 3 + 3 + 4, 3 × 3 × 4 = 36。
解题思路:动态规划
-
确定dp数组以及下标的含义
dp[i] 代表数 i 拆分后的最大乘积
-
确定递推公式
根据从1开始遍历 j ,dp[i] 有两种拆分模式:
- 简单拆分为两个数相乘,即 j * ( i - j ) ;
- 将 j 保留,( i - j ) 拆分为多个数,取相乘的最大乘积 dp[ i - j ],即 j * dp[ i - j ]
根据上述两种模式,j 每次加 1 都要取两种模式的最大值,简化该步骤可得递推公式:
dp[i] = Math.max( dp[i] , (i-j)*j , dp[i-j]*j )
-
dp数组如何初始化
根据实际逻辑可知 dp[0] 与 dp[1] 都无实际意义,因此初始化dp[2] = 1*1 = 1
同时,由于每次遍历 j 的比较中都会使用到 dp[i] ,因此要先给整个dp数组初始化为 0 ,否则将出现 NaN 的情况。
-
确定遍历顺序
由于我们初始化了dp[2],我们从i = 3 开始遍历,遍历到 n ,即
for(let i=3; i<=n; i++)
内部遍历 j ,我们从 j=1 开始遍历,遍历到满足 i - j >1 的最大值,即
for(let j=1; j<i; j++)
-
举例推导dp数组
根据实际情况可知 dp[6] = 9,dp[7] = 12,dp[8] = 16,求 dp[9]
j=1,max = ( ( 9-1 ) * 1 , dp[ 9-1 ] * 1 ) = 16
j=2,max = ( ( 9-2 ) * 2 , dp[ 9-2 ] * 2 ) = 24
j=3,max = ( ( 9-3 ) * 3 , dp[ 9-3 ] * 3 ) = 27 (最大值)
…….
j=7,max = ( ( 9-7 ) * 7 , dp[ 9-7 ] * 7 ) = 14
JavaScript 代码如下:
var integerBreak = function(n) {
let dp = new Array(n+1).fill(0)
dp[2] = 1
for(let i = 3;i<=n;i++){
for(let j=1;j<i-1;j++){
dp[i] = Math.max(dp[i],(i-j)*j,dp[i-j]*j)
}
}
return dp[n]
};