整数拆分
给定一个正整数 n ,将其拆分为 k 个 正整数 的和( k >= 2 ),并使这些整数的乘积最大化。
返回 你可以获得的最大乘积 。
思路:其实这题很简单,之所以难度中等估计是因为要两步吧。经过一波初中生都会的推导,发现模 3 余 0,2 的情况选尽可能多的 3 ,余 1 选一个 4 剩下全选 3 即可。接下来的问题才是程序员该重点思考的:如何计算?
快速幂取余:假设通过分析,我们得到应该选 a 个 3,剩下 b ,只要计算
3
a
∗
b
%
p
3^a*b\%p
3a∗b%p(p为要求取的模即可),关键在于
3
a
%
p
3^a\% p
3a%p。运用快速幂算法时,原理就是运用以下恒等式反复迭代,最终将 a 降为 0 次,rem 即为结果。
r
e
m
∗
x
a
≡
{
r
e
m
∗
(
x
2
)
a
2
i
f
a
%
2
=
0
(
r
e
m
∗
x
)
∗
x
a
−
1
i
f
a
%
2
=
1
(
m
o
d
p
)
rem*x^a\equiv \left\{ \begin{aligned} rem*(x^2)^\frac{a}{2}~~~~~~~ if~a\%2 =0\\ (rem*x)*x^{a-1}~~if~a\%2 =1\\ \end{aligned} \right.(mod~p)
rem∗xa≡{rem∗(x2)2a if a%2=0(rem∗x)∗xa−1 if a%2=1(mod p)
最终代码:
class Solution {
public:
int mod=1e9+7;
int cuttingRope(int n) {
if(n<=3){return n-1;}
int a=(n%3==1?n/3-1:n/3);
int b=n-3*a;
long long x=3;
long long rem=1;
while(a){
if(a%2!=0){rem=(rem*x)%mod;}
x=(x*x)%mod;
a/=2;
}
if(b){rem=(rem*b)%mod;}
return rem;
}
};