题目要求
整数拆分
给定一个正整数 n,将其拆分为至少两个正整数的和,并使这些整数的乘积最大化。 返回你可以获得的最大乘积。
示例 1:
输入: 2
输出: 1
解释: 2 = 1 + 1, 1 × 1 = 1。
示例 2:
输入: 10
输出: 36
解释: 10 = 3 + 3 + 4, 3 × 3 × 4 = 36。
说明: 你可以假设 n 不小于 2 且不大于 58。
解题思路
简单数学分析
假如n只拆成两个整数并做积, 可以直接得出:
- 如果n是偶数:
- f ( n ) = 1 4 n 2 . f(n)=\dfrac14n^2. f(n)=41n2.
- 如果n是奇数:
- f ( n ) = 1 4 ( n 2 − 1 4 ) . f(n)=\dfrac14\left(n^2-\dfrac14\right). f(n)=41(n2−41).
易证得在
n
>
4
n>4
n>4时有
f
(
n
)
>
n
f(n)>n
f(n)>n成立.
现在题目要求至少两个整数, 所以将流程变为拆分→再拆分的过程. 让每一阶段都满足
f
(
n
)
>
n
f(n)>n
f(n)>n即可. 唯一的问题在于需要拆到什么程度才算最优.
解题方案
数学方法
设将
n
n
n拆成
a
a
a个正数
x
x
x相乘后有最大乘积, 则有
f
(
x
)
=
x
a
f(x)=x^a
f(x)=xa
其中
a
=
n
x
.
a=\dfrac nx.
a=xn.
要想求在
x
x
x取多大的整数有
f
(
x
)
=
m
a
x
{
f
(
x
)
}
f(x)=max\{f(x)\}
f(x)=max{f(x)}, 则需要求
f
(
x
)
f(x)
f(x)的单调性.
由上,可知
f
(
x
)
=
x
n
x
=
e
ln
x
⋅
n
x
f(x)=x^{\frac nx}=e^{\text{ln} x\cdot \frac nx}
f(x)=xxn=elnx⋅xn
由于
y
=
e
x
y=e^x
y=ex为单调增函数,所以
f
(
x
)
f(x)
f(x)的单调性与
x
(
t
)
=
ln
t
t
x(t)=\dfrac{\text{ln}t}t
x(t)=tlnt相同.
x
′
(
t
)
=
0
x'(t)=0
x′(t)=0时,
t
=
e
t=e
t=e.
x
′
′
(
e
)
<
0
x''(e)<0
x′′(e)<0, 可知
t
=
e
t=e
t=e是
x
(
t
)
=
ln
t
t
x(t)=\dfrac{\text{ln}t}t
x(t)=tlnt的极大值点, 同时也是
f
(
x
)
=
e
ln
x
⋅
n
x
f(x)=e^{\text{ln} x\cdot \frac nx}
f(x)=elnx⋅xn的极大值点.
f
(
x
)
f(x)
f(x)定义域连续, 有
m
a
x
{
f
(
x
)
}
=
f
(
e
)
max\{f(x)\}=f(e)
max{f(x)}=f(e). 所以最优正数为
e
e
e. 此题求一正整数, 所以取
e
e
e两侧最近整数2和3作比较. 比较方法为比较
f
(
2
)
f(2)
f(2)和
f
(
3
)
f(3)
f(3)的大小. 也是比较
x
(
2
)
x(2)
x(2)和
x
(
3
)
x(3)
x(3)的大小. 经过计算显然
x
(
3
)
>
x
(
2
)
x(3)>x(2)
x(3)>x(2),则
f
(
3
)
>
f
(
2
)
f(3)>f(2)
f(3)>f(2), 所以在拆分时尽可能的将其拆分为3, 用2补充.
代码
class Solution {
public:
int integerBreak(int n)
{
int last = n % 3;
int a = (n - last) / 3;
if (n <= 3)
return n - 1;
else
switch (last)
{
case 0:
return pow(3, a);
case 1:
return pow(3, a - 1) * 4;
case 2:
return pow(3, a) * 2;
default:
return 0;
}
}
};