链接
问题
将正整数 n n n 分拆成若干不等的正整数 a i a_i ai,使得 s = ∏ i = 1 r a i s=\prod_{i=1}^ra_i s=∏i=1rai最大,求最大值对的 1 0 9 + 7 10^9+7 109+7模
分拆方案
分拆方案举例
- 例1:
n
=
14
n=14
n=14,分拆方案:
- 2、3、4、5 共4项, s = 2 ∗ 3 ∗ 4 ∗ 5 = 120 s = 2*3*4*5 = 120 s=2∗3∗4∗5=120
- 3、5、6 共3项, s = 3 ∗ 5 ∗ 6 = 90 s = 3*5*6 = 90 s=3∗5∗6=90
- ⋯ ⋯ \cdots\cdots ⋯⋯
- 例2:
n
=
16
n=16
n=16,分拆方案:
- 2、3、5、6 共4项, s = 2 ∗ 3 ∗ 5 ∗ 6 = 180 s = 2*3*5*6 = 180 s=2∗3∗5∗6=180
- 2、3、4、7 共4项, s = 2 ∗ 3 ∗ 4 ∗ 7 = 168 s = 2*3*4*7 = 168 s=2∗3∗4∗7=168
- ⋯ ⋯ \cdots\cdots ⋯⋯
- 例3:
n
=
18
n=18
n=18,分拆方案:
- 3、4、5、6 共4项, s = 3 ∗ 4 ∗ 5 ∗ 6 = 360 s = 3*4*5*6 = 360 s=3∗4∗5∗6=360
- 4、5、9 共3项, s = 4 ∗ 5 ∗ 9 = 180 s = 4*5*9 = 180 s=4∗5∗9=180
- ⋯ ⋯ \cdots\cdots ⋯⋯
- 例4:
n
=
19
n=19
n=19,分拆方案:
- 3、4、5、7 共4项, s = 2 ∗ 3 ∗ 4 ∗ 5 = 120 s = 2*3*4*5 = 120 s=2∗3∗4∗5=120
- 3、5、6 共3项, s = 3 ∗ 5 ∗ 6 = 90 s = 3*5*6 = 90 s=3∗5∗6=90
- 例5:
n
=
20
n=20
n=20,分拆方案:
- 2、3、4、5、6 共5项, s = 2 ∗ 3 ∗ 4 ∗ 5 ∗ 6 = 720 s = 2*3*4*5*6 = 720 s=2∗3∗4∗5∗6=720
- ⋯ ⋯ \cdots\cdots ⋯⋯
分拆方案总结
- 分拆方案不含1(贪心思想:1对积无贡献)
- 对于给定的n,可以得到不含1的最大的分拆数k及其(唯一)方案(贪心思想:每一项尽量小)
∑ i = 2 k + 1 i ≤ n < ∑ i = 2 k + 2 i 或 n = ∑ i = 2 k + 1 i + r , 0 ≤ r ≤ k + 1 , 即 : \sum_{i=2}^{k+1}i\leq n < \sum_{i=2}^{k+2}i \quad 或 \quad n=\sum_{i=2}^{k+1}i+r,0\leq r \leq k+1,即: i=2∑k+1i≤n<i=2∑k+2i或n=i=2∑k+1i+r,0≤r≤k+1,即:
n = ∑ i = 2 k + 1 i + r = { 2 + 3 + ⋯ + k + ( k + 1 ) ⏞ k 项 , 当 r = 0 2 + ⋯ + ( k + 1 − r ) ⏞ k − r 项 + ( k + 3 − r ) + ⋯ + ( k + 2 ) ⏞ r 项 , 当 1 ≤ r < k 3 + 4 + ⋯ + ( k + 1 ) + ( k + 2 ) ⏞ k 项 , 当 r = k 3 + 4 + ⋯ + ( k + 1 ) ⏞ k − 1 项 + ( k + 3 ) , 当 r = k + 1 n =\sum_{i=2}^{k+1}i+r= \begin{cases} \overbrace{2+3+\cdots+k+(k+1)}^{k\,项}, & \text{当 $r=0$} \\ \overbrace{2+\cdots+(k+1-r)}^{k-r\,项}+\overbrace{(k+3-r)+\cdots+(k+2)}^{r\,项}, & \text{当 $1\leq r<k$} \\ \overbrace{3+4+\cdots+(k+1)+(k+2)}^{k\,项}, & \text{当 $r=k$} \\ \overbrace{3+4+\cdots+(k+1)}^{k-1\,项}+(k+3), & \text{当 $r=k+1$} \\ \end{cases} n=i=2∑k+1i+r=⎩⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎨⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎧2+3+⋯+k+(k+1) k项,2+⋯+(k+1−r) k−r项+(k+3−r)+⋯+(k+2) r项,3+4+⋯+(k+1)+(k+2) k项,3+4+⋯+(k+1) k−1项+(k+3),当 r=0当 1≤r<k当 r=k当 r=k+1
特别的,当 n = 4 n=4 n=4 时,则 k = 1 k=1 k=1,即分拆方案为 { 4 } \{4\} {4} - 有不含1的最大的分拆数k时,积
s
s
s 最大。证明如下:
- 设 n = a 1 + a 2 + ⋯ + a k 且 a 1 < a 2 < ⋯ < a k 且 a 1 = 2 或 3 或 4 n=a_1+a_2+\cdots+a_k 且 a_1 < a_2 < \cdots <a_k且a_1=2\,或\,3\,或\,4 n=a1+a2+⋯+ak且a1<a2<⋯<ak且a1=2或3或4,是不含1的最大分拆数方案
- 设
n
=
b
1
+
b
2
+
⋯
+
b
j
且
1
<
b
1
<
b
2
<
⋯
<
b
j
且
j
<
k
n=b_1+b_2+\cdots+b_j 且 1 < b_1 < b_2 < \cdots <b_j且j<k
n=b1+b2+⋯+bj且1<b1<b2<⋯<bj且j<k,是不含1的分拆方案,则
∏ i = 1 j b i < ∏ i = 1 j a i , 即 最 大 分 拆 数 方 案 对 应 的 积 s 最 大 \prod_{i=1}^jb_i < \prod_{i=1}^ja_i,即最大分拆数方案对应的积s最大 i=1∏jbi<i=1∏jai,即最大分拆数方案对应的积s最大 - 规则1:若
3
<
a
1
<
a
2
3 < a_1 < a_2
3<a1<a2,则
2
⋅
(
a
1
−
1
)
⋅
(
a
2
−
1
)
>
a
1
⋅
a
2
2\cdot (a_1-1) \cdot (a_2-1) > a_1\cdot a_2
2⋅(a1−1)⋅(a2−1)>a1⋅a2.
∵ 2 ⋅ ( a 1 − 1 ) ⋅ ( a 2 − 1 ) − a 1 ⋅ a 2 = ( a 1 − 2 ) ⋅ a 2 − 2 a 1 + 2 ≥ ( a 1 − 2 ) ⋅ a 2 − 2 a 2 + 2 = ( a 1 − 4 ) ⋅ a 2 + 2 ≥ 2 ∴ 2 ⋅ ( a 1 − 1 ) ⋅ ( a 2 − 1 ) > a 1 ⋅ a 2 , 即 将 2 项 拆 成 3 项 \because \quad 2\cdot (a_1-1) \cdot (a_2-1) - a_1\cdot a_2\\ =(a_1-2)\cdot a_2-2a_1+2\\ \geq (a_1-2)\cdot a_2-2a_2+2\\ =(a_1-4)\cdot a_2+2 \geq 2 \\ \therefore \quad 2\cdot (a_1-1) \cdot (a_2-1) > a_1\cdot a_2, 即将2项拆成3项 ∵2⋅(a1−1)⋅(a2−1)−a1⋅a2=(a1−2)⋅a2−2a1+2≥(a1−2)⋅a2−2a2+2=(a1−4)⋅a2+2≥2∴2⋅(a1−1)⋅(a2−1)>a1⋅a2,即将2项拆成3项 - 规则2:若
4
≤
a
4\leq a
4≤a,则
a
≤
2
(
a
−
2
)
a \leq 2(a-2)
a≤2(a−2)
∵ 2 ( a − 2 ) − a = a − 4 ≥ 0 ∴ a ≤ 2 ( a − 2 ) , 即 将 1 项 拆 成 2 项 \because \quad 2(a-2)-a= a-4 \geq 0\\ \,\\ \therefore \quad a \leq 2(a-2),即将 1 项拆成 2 项 ∵2(a−2)−a=a−4≥0∴a≤2(a−2),即将1项拆成2项 - 规则3:若
1
≤
a
1
<
a
2
1\leq a_1 < a_2
1≤a1<a2,则
a
1
∗
a
2
≤
(
a
1
+
1
)
(
a
2
−
1
)
a_1*a_2 \leq (a_1+1)(a_2-1)
a1∗a2≤(a1+1)(a2−1)
∵ ( a 1 + 1 ) ( a 2 − 1 ) − a 1 ⋅ a 2 = a 2 − a 1 − 1 ≥ 0 ∴ ( a 1 + 1 ) ( a 2 − 1 ) ≥ a 1 ⋅ a 2 \because \quad (a_1+1)(a_2-1)- a_1\cdot a_2= a_2-a_1-1 \geq 0\\ \,\\ \therefore \quad (a_1+1)(a_2-1) \geq a_1\cdot a_2 ∵(a1+1)(a2−1)−a1⋅a2=a2−a1−1≥0∴(a1+1)(a2−1)≥a1⋅a2 - 通过规则1-3,将 { b 1 , ⋯ , b j } \{b_1,\cdots,b_j\} {b1,⋯,bj}方案转化为 { a 1 , ⋯ , a k } \{a_1,\cdots,a_k\} {a1,⋯,ak}方案,转化过程中积 s s s 不变小
算法分析
- 先计算k,利用 2 , 3 , 4 , 5 , ⋯ 2,3,4,5, \cdots 2,3,4,5,⋯ 的前缀和和二分搜索计算 k k k
- 计算 2 ⋯ k % m 2\cdots k\,\%\,m 2⋯k%m
- 分情况计算
代码
- 扩展欧几里得求逆元
// hdu 5976 Detachment
#include<bits/stdc++.h>
using namespace std;
#define MOD 1000000007
#define MAX 45000
int K[MAX], M[MAX];
// ax + by = (a, b)
int ex_gcd(int a, int b, int &x, int &y){
int d;
// a = (a, 0) = (a, b)
if(b == 0){
x = 1, y = 0;
return a;
}
// b(y+a/bx) + a%bx = (b, a%b)
d = ex_gcd(b, a%b, x, y);
int tmp = x;
x = y;
y = tmp - a/b*y;
return d;
}
int main(){
int t, n, k, r, ans, x, y;
K[1] = 2, M[1] = 2;
for(int i=2; i < MAX; ++i) K[i] = K[i-1]+i+1;
for(int i=2; i < MAX; ++i) M[i] = 1LL*M[i-1]*(i+1)%MOD;
scanf("%d", &t);
while(t--){
scanf("%d", &n);
if(n < 5){
printf("%d\n", n);
continue;
}
k = lower_bound(K+1, K+MAX, n)-K;
if(K[k] > n) k--;
r = n - K[k];
if(r == 0) ans = M[k];
else if(r == k){
ans = M[k+1];
ex_gcd(2, MOD, x, y);
ans = 1LL * ans * x % MOD;
}
else if(r == k+1){
ans = M[k];
ex_gcd(2, MOD, x, y);
ans = 1LL * ans * x % MOD;
ans = 1LL * ans * (k+3) % MOD;
}
else{
ans = M[k+1];
ex_gcd(k+2-r, MOD, x, y);
ans = 1LL * ans * x % MOD;
}
printf("%d\n", (ans+MOD)%MOD);
}
return 0;
}
- 线性求逆元
// hdu 5976 Detachment
#include<bits/stdc++.h>
using namespace std;
#define MOD 1000000007
#define MAX 45000
int K[MAX], M[MAX], inv[MAX];
int main(){
int t, n, k, r, ans, x, y;
K[1] = 2, M[1] = 2, inv[1]=1;
for(int i=2; i < MAX; ++i) K[i] = K[i-1]+i+1;
for(int i=2; i < MAX; ++i) M[i] = 1LL*M[i-1]*(i+1)%MOD;
for(int i=2; i < MAX; ++i) inv[i] = 1LL*(MOD-MOD/i)*inv[MOD%i]%MOD;
scanf("%d", &t);
while(t--){
scanf("%d", &n);
if(n < 5){
printf("%d\n", n);
continue;
}
k = lower_bound(K+1, K+MAX, n)-K;
if(K[k] > n) k--;
r = n - K[k];
if(r == 0) ans = M[k];
else if(r == k){
ans = M[k+1];
ans = 1LL * ans * inv[2] % MOD;
}
else if(r == k+1){
ans = M[k];
ans = 1LL * ans * inv[2] % MOD;
ans = 1LL * ans * (k+3) % MOD;
}
else{
ans = M[k+1];
ans = 1LL * ans * inv[k+2-r] % MOD;
}
printf("%d\n", (ans+MOD)%MOD);
}
return 0;
}