[算法笔记]leetcode 343 整数拆分
leetcode 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
思路推导
先试几个数
| num | 和 | 积 | |
|---|---|---|---|
| 1 | 1 + 0 | 0 | 不能拆 |
| 2 | 1 +1 | 1 | |
| 3 | 1 + 2 | 2 | 2可以拆 |
| 2 + 1 | 2 | 2可以拆 | |
| 1 + 1 + 1 | 1 | 1不能拆 | |
| 4 | 1 +3 | 3 | 3 可以拆 |
| 2 + 2 | 4 | 2 可以拆 | |
| 3 + 1 | 3 | 1不能拆 | |
| 1 + 1 + 2 | 2 | 2可以拆 | |
| 1 + 2 + 1 | 2 | 2可以拆 | |
| 2 + 1 + 1 | 2 | 2可以拆 | |
| 1 + 1+ 1+1 | 1 | 1不能拆 |
分析:
以 num = 4 为例子,可以拆成 1,3。
i. 拆成两个数字:直接相乘,乘积为3,
ii. 拆成n个数字(n>=3), 其中3 可以进行拆分 。要明确拆的目的是要求 1*[...] 的最大值,也就是求 3 拆成的相加序列[....] 的乘积的最大值。 可以看出 求3拆分的最大值是 其子问题。
确定dp[], dp[i] 为数字 i 拆分后乘积最大的数值,i 为数字i
也就是说:情况1: 两数相乘;情况2:多数相乘 中选值最大的。
$dp[i] = max{{i(i-j),j*dp[i-j],dp[i]}}$
注:max 中有dp[i],是由于内循环中 j 的每次变化会更新一次dp[i],要保证遍历完 j 后 dp[i] 中的数字为最大值。
代码
#include<bits/stdc++.h>
using namespace std;
class Solution {
private:
int get_max(int num1,int num2,int num3){
int tm1 = max(num1,num2);
int tm2 = max(num2,num3);
return max(tm1,tm2);
}
public:
int integerBreak(int n) {
vector<int> dp(n+1,0);
for(int i = 2;i<=n;i++){
for(int j = 1;j<i;j++){
dp[i] = get_max(j*dp[i-j],j*(i-j),dp[i]);
// cout<<i<<" "<<j<<endl;
} } return dp[n];
}
};
贪心的做法
$3m +k$ : m 个三 加剩余的数字
$3^{m}k$: 相乘

浙公网安备 33010602011771号