343. 整数拆分
给定一个正整数 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、确定dp数组(dp)以及下标的含义
dp[i]:分拆数字i,可以得到的最大乘积为dp[i]。
2、确定递推公式
dp[i]最大乘积得到的方式:
- 一个是j*(i-j)直接相乘
- 一个是j*dp[i-j],相当于是拆分(i-j)
dp[i] = max(dp[i], max((i-j) * j, dp[i-j]*j));
理解:j * (i - j) 是单纯的把整数拆分为两个数相乘,而j * dp[i - j]是拆分成两个以及两个以上的个数相乘。
3、dp数组的初始化
dp[1]=0,dp[2]=1
4、遍历顺序
从前往后遍历即可
for(int i = 3; i <= n; i++) {
for(int j = 0; j < i; j++) {
dp[i] = max(dp[i], max((i - j) * j, dp[i - j] * j));
}
}
进一步的优化
for(int i = 3; i <= n; i++) {
for(int j = 0; j <= i / 2; j++) {
dp[i] = max(dp[i], max((i - j) * j, dp[i - j] * j));
}
}
5、举例推导dp数组
import java.util.*;
class Solution {
public int integerBreak(int n) {
int[] dp = new int[n+1];
dp[1] = 0;
dp[2] = 1;
for (int i = 3; i <= n; i++) {
for (int j = 0; j < i; j++) {
dp[i] = Math.max(dp[i], Math.max((i-j)*j, dp[i-j] * j));
}
}
return dp[n];
}
}
标签:06,乘积,int,整数,相乘,拆分,dp
From: https://www.cnblogs.com/codingbao/p/18215785