【Leetcode】NO.343 整数的拆分 (C++&Python) [动态规划]
题目:整数的拆分
给定一个正整数 n,将其拆分为至少两个正整数的和,并使这些整数的乘积最大化。 返回你可以获得的最大乘积。
思路
- 动态规划题
- 对于i对应的是i的最大乘积,索引从1开始dp数组开n+1;
- 对于j对应的是拆分数,索引从1开始,最大到i-1(最后是n-1);
- 每个位置的最大值是对于拆分j*dp[i-j], 和 直接拆j *(i-j),选择最大;
- 最后直接返回dp[n]
在看题解的时候看到了使用数学的方法进行coding,很灵活;
大概意思是拆分的是尽可能拆分成3:
这是因为例如:
5,6这些大于3的,如果不拆分则为本身;
拆分的话(5=2+3<2*3),6=2+2+2=3+3 ==>(2*2*2 < 3*3),只要是大于4的数直接拆分成3,直到不能继续拆分为止;(ps:这里的6继续拆分之后数值比原来要打,之后就是比较拆分中哪种最大,很明显拆分成3的要比其他大)
说明拆分成2要小于拆分成3的,这是利用数学证明的;
代码
Python 版本
class Solution:
def integerBreak(self, n: int) -> int:
# dp 求解
dp = [0]*(n+1)
dp[2] = 1
for i in range(3,n+1): # 0不用
for j in range(1,i-1): # 从1开始拆分, {1,1....} 最大拆到n-1,用i来表示是i-1,右边是取不到的,但是i是重索引1开始当i是能够索引到n 的,所以i-1索引到n-1
dp[i] = max(dp[i], dp[i-j]*j, (i-j)*j)
return dp[n]
C++ 版本
class Solution {
public:
int integerBreak(int n) {
vector<int> dp(n+1,0);
dp[2] = 1;
for(int i=3;i<dp.size();i++)
{
for(int j=1;j<i-1;j++)
{
dp[i] = max(dp[i],max(dp[i-j]*j, (i-j)*j));
}
}
return dp[n];
}
};
运行结果图
本文来自博客园,作者:jucw,转载请注明原文链接:https://www.cnblogs.com/Jucw/p/15758672.html