力扣刷题笔记(五)
343. 整数拆分
难度:中等⭐️⭐️⭐️⭐️
题目
给定一个正整数 n ,将其拆分为 k 个 正整数 的和( k >= 2 ),并使这些整数的乘积最大化。
返回 你可以获得的最大乘积 。
示例 1:
输入: n = 2
输出: 1
解释: 2 = 1 + 1, 1 × 1 = 1。
示例 2:
输入: n = 10
输出: 36
解释: 10 = 3 + 3 + 4, 3 × 3 × 4 = 36。
提示:
- 2 <= n <= 58
代码
- 动态规划
class Solution {
public int integerBreak(int n) {
int[] dp = new int[n+1];
dp[1] = 1;
for (int i = 2; i <= n; i++) {
for (int j = 0; j <= i; j++) {
dp[i] = Math.max(dp[i], Math.max(dp[i-j], i-j) * j);
}
}
return dp[n];
}
}
笔记
- 动态规划:dp[i]表示拆分整数i可以得到的最大乘积。
一般来说:dp[i] = max(dp[i-j] * j), j=0,1,..., i,这个好理解,就是凑成i能得到的最大乘积就等于凑成i-j的最大乘积乘以j。举例来说:
dp[0] = 0,表示凑成0的k个整数的乘积最大值为0;
dp[1] = 1,表示凑成1的k个整数的乘积最大值为1;
j为什么可以取0,举例来说明:
dp[2] = max(dp[2] * 0, dp[1] * 1) = max(0, 1) = 1;
dp[3] = max(dp[3] * 0, dp[2] * 1, dp[1] * 2)? 确定吗?dp[3]真是这样转移的吗?
dp[2]=1是没错,但是,当计算dp[3]的时候,取dp[3] = dp[2] * 1 = 1 * 1 = 1的时候,dp[2]表示2被拆成1+1,也即3被拆成1+1+1。其实,3应该被拆成2 + 1或者1 + 2,乘积才是最大的。总的来说,计算dp[3]的时候,不是直接取dp[2],而是应该看dp[2]和2谁大谁小,取大的那一个,对于3来说,要看2是取被拆还是不被拆,两者的最大值。
所以,dp[3] = max(dp[3] * 0, max(dp[2], 2) * 1, max(dp[1], 1) * 2) = max(0, 2, 2) = 2。
所以,真正的状态转移方程是:dp[i] = max(max(d[i-j], i-j) * j), j=0,1,..., i
我开源了一份武林秘籍,欢迎⭐️star:
创作不易,喜欢的话加个关注点个赞,❤谢谢谢谢❤
文章讲述了如何使用动态规划方法解决整数拆分问题,以求得将正整数n拆分成k个部分时,使得乘积最大。关键在于正确理解状态转移方程dp[i]=max(max(dp[i-j],i-j)*j),其中j=0,1,...,i。
653

被折叠的 条评论
为什么被折叠?



