leetcode 343 Integer Break
Given a positive integer n, break it into the sum of at least two positive integers and maximize the product of those integers. Return the maximum product you can get.
For example, given n = 2, return 1 (2 = 1 + 1); given n = 10, return 36 (10 = 3 + 3 + 4).
Note: You may assume that n is not less than 2 and not larger than 58.
思路:因为n最大为58所以可以随便搞啊。
其实可以想到最优子结构,dp[n]为拆分n能得到的最大值。 比如dp[5]可以由dp[4]*1,dp[3]*2,dp[2]*3,dp[1]*4
或4*1,3*2,2*3,1*4
取最大值得到。代码如下:
class Solution {
public:
int dp[60];
int integerBreak(int n) {
dp[2] = 1;
dp[1] = 1;
for (int i = 3; i <= n; ++i) {
for (int j = 1; j < i; ++j) {
dp[i] = max(j * (i - j), dp[i]);
dp[i] = max(dp[i - j] * j, dp[i]);
}
}
return dp[n];
}
};
这道题目的另一个解法是数学方法,由均值不等式(n个数的算术平均值大于等于它们的几何平均值):
链接
算数平均值:
几何平均值:
leetcode 343 Integer Break
算术-几何平均值不等式表明,对任意的正实数 x1,x2,x3....,总有:
等号成立当且仅当x1=x2=x3=x4....xn
对于这道题目x1+x2+x3...xn的和是固定的,关键是怎么求出x1,x2,x3...xn,因为要使乘积最大,所以x1=x2=x3=x4....=xn。那么我们可以得到x1=x2=x3=....xn=N/n这里N是题目中的输入,n是个数。现在的问题是如何求出x1,x2,x3...xn,那么我们可以列出来一个方程。
设f(x)为分成N/x个数能得到的最大乘积值,那么f(x)=x^(N/x)
,求导数得到f'(x)=N/x^2*x^(10/x)*(1-log(x))
即当x为e的时候取得最大值。但是本体中要求是整数,所以x尽量取3就能得到最大值了,取不到3取2为最优。
如图,当N为10的时候曲线如下:
class Solution {
public:
int integerBreak(int n) {
if (n==2) return 1;
if (n==3) return 2;
int product = 1;
while (n>4)
{
product*=3;
n-=3;
}
product*=n;
return product;
}
};
欢迎关注公众号: