2018年长沙理工大学程序设计竞赛 J - 杯子

题意: 链接:https://www.nowcoder.com/acm/contest/96/J
一天durong同学买了一个无限长的杯子,同时买了n个球,并且标号为1,2,3......n,durong同学突然想到一个问题----如果他把n个球依次,

也就是按照1,2,3...n的顺序放进杯子里,然后在全部拿出来(注意不一定要等到全部放进去才能拿出球),并且会记录放进和拿出球的顺序,
durong想知道,要满足当第m个球进去后,杯子中此时恰好有k个球,然后仍然要把剩下的n-m个球放进去,最后杯中的球要取光,

这样的放进和拿出球的顺序有多少种,答案有可能很大,所以mod上1e9+7。

kuangbing的博客

这个题解讲的挺好的

对于n个0,m个1 的任意前缀0的个数不小于1的种数是 C(n+m,n)-C(n+m,m-1)。

卡特兰数是n = m 的特殊情况, 通项公式为 C(2 * n, n) / (n + 1)

 1 #include<bits/stdc++.h>
 2 #define LL long long
 3 #define fi first
 4 #define se second
 5 #define mk make_pair
 6 #define pii pair<int,int>
 7 using namespace std;
 8 
 9 const int N=2e6+7;
10 const int M=1e4+7;
11 const int inf=0x3f3f3f3f;
12 const LL INF=0x3f3f3f3f3f3f3f3f;
13 const int mod=1e9 + 7;
14 
15 int n, m, k;
16 LL f[N], inv[N];
17 
18 LL fastPow(LL a, LL b) {
19     LL ans = 1;
20     while(b) {
21         if(b & 1) ans = ans * a % mod;
22         a = a * a % mod; b >>= 1;
23     }
24     return ans;
25 }
26 void init() {
27     f[0] = 1;
28     for(int i = 1; i < N; i++) {
29         f[i] = f[i - 1] * i % mod;
30     }
31     for(int i = N - 1; i >= 0; i--)
32         inv[i] = fastPow(f[i], mod - 2);
33 
34 }
35 
36 LL C(int n, int m) {
37     if(n < m) return 0;
38     return f[n] * inv[m] % mod * inv[n - m] % mod;
39 }
40 
41 LL getCatalan(int n, int m) {
42    return (C(n + m, n) - C(n + m, m - 1) + mod) % mod;
43 }
44 
45 int main() {
46     init();
47     int T; scanf("%d", &T);
48     while(T--) {
49         scanf("%d%d%d", &n, &m, &k);
50         if(m > n || k > m) {
51             puts("0");
52             continue;
53         }
54         LL ret1 = getCatalan(m - 1, m - k);
55         LL ret2 = getCatalan(n - (m - k), n - m);
56         printf("%lld\n", ret1 * ret2 % mod);
57     }
58     return 0;
59 }
60 /*
61 */
扫描二维码关注公众号,回复: 109257 查看本文章

猜你喜欢

转载自www.cnblogs.com/CJLHY/p/8990020.html
今日推荐