这一题可能拆为2个数,3个数甚至更多的时候,因为几何均值总是小于等于算术均值:
a
1
+
a
2
+
⋯
+
a
n
n
⩾
a
1
⋅
a
2
⋯
⋯
a
n
n
\frac{a_{1}+a_{2}+\cdots+a_{n}}{n} \geqslant \sqrt[n]{a_{1} \cdot a_{2} \cdots \cdots a_{n}}
na1+a2+⋯+an⩾na1⋅a2⋯⋯an
当且仅当 a 1 = a 2 = . . . = a n a1=a2=...=an a1=a2=...=an的时候等号成立。所以我们知道若拆分的数量确定, 则均匀拆分时,乘积最大。
以下证明很简单。
假设将 n 等分为 a 份,每份为 x,则有
n
=
a
x
n = ax
n=ax,乘积为
x
a
x^a
xa,有
x a = x n / x = ( x 1 / x ) n x^a = x^{n/x} = (x^{1/x})^{n} xa=xn/x=(x1/x)n
n 为常数,所以要使乘积最大即求 y = x 1 / x y = x^{1/x} y=x1/x的极大值,直接求导容易得到 x 0 = e x_0 = e x0=e 时取得极大值,而我们的题目要求了 x 必须为整数,最接近 e 的整数是2或3,分别带入2和3可以知道 x = 3 x = 3 x=3时取得最大值。
所以 我们的拆分规则为:
- 将n尽可能的拆分为多个数字3
- 最后留下的余数可能如果为2:就不需要拆为两个1了
- 最后留下的余数如果是1,那么我们应该取出一个3来,将3+1变为2+2,因为(1 * 3 < 2 * 2)
class Solution {
public:
int integerBreak(int n) {
if(n <= 3) return n-1;
// n = a* 3 + b
int a = n/3, b = n%3; //a为整数部分,b为余数部分
if(b == 0) return pow(3,a);
if(b == 1) return pow(3, a-1)*4;
return pow(3, a)*2;// b == 2
}
};
动态规划:
动态规划解拆分整数I[Silver Fox] - 整数拆分 - 力扣(LeetCode)
class Solution {
public:
int integerBreak(int n) {
vector<int> a(n+1, 0);
for(int i = 2; i <= n; ++i){
for(int j = 1; j < i; ++j){
a[i] = max(a[i], j*max(i-j, a[i-j]));
}
}
return a[n];
}
};