UVA11806 Cheerleaders

Cheerleaders

 

大意:n * m个网格中放若干石子,要求最上面一行、最下面一行、最左边一列、最右边一列必须有石子

 

没有石子比有石子好求,考虑容斥

小集合是最上面一行没有、最下面一行没有、最左边一列没有、最右边一列没有

 

注意MOD不是质数!

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <cstdlib>
 5 #include <algorithm>
 6 #include <queue>
 7 #include <vector>
 8 #define min(a, b) ((a) < (b) ? (a) : (b))
 9 #define max(a, b) ((a) > (b) ? (a) : (b))
10 #define abs(a) ((a) < 0 ? (-1 * (a)) : (a))
11 inline void swap(long long &a, long long &b)
12 {
13     long long tmp = a;a = b;b = tmp;
14 }
15 inline void read(long long &x)
16 {
17     x = 0;char ch = getchar(), c = ch;
18     while(ch < '0' || ch > '9') c = ch, ch = getchar();
19     while(ch <= '9' && ch >= '0') x = x * 10 + ch - '0', ch = getchar();
20     if(c == '-') x = -x;
21 }
22 
23 const long long INF = 0x3f3f3f3f;
24 const long long MAXK = 500;
25 const long long MAXN = 20;
26 const long long MOD = 1000007;
27 
28 long long n,m,k,t,C[MAXN * MAXN + 5][MAXK + 5];
29 
30 int main()
31 {
32     read(t);long long cnt = 0;
33     C[0][0] = 1;
34     for(register int i = 0;i <= MAXN * MAXN;++ i)
35     {
36         C[i][0] = 1;C[i][i] = 1;
37         for(register int j = 1;j <= i;++ j)
38             C[i][j] = (C[i - 1][j - 1] + C[i - 1][j]) % MOD;
39     }
40     for(;t;--t)
41     {
42         ++ cnt;
43         read(n), read(m), read(k);
44         long long ans = 0;
45         for(long long S = 0;S < 16;++ S)
46         {
47             long long num = 0, a = n, b = m;
48             if(S & 1) -- a, ++ num;
49             if(S & 2) -- b, ++ num;
50             if(S & 4) -- a, ++ num;
51             if(S & 8) -- b, ++ num;
52             if(num & 1) ans = (ans - C[a* b][k] + MOD) % MOD;
53             else ans = (ans + C[a * b][k]) % MOD;
54         }
55         printf("Case %lld: %lld\n", cnt, ans);
56     }
57     return 0;
58 } 
UVA11806

 

posted @ 2018-01-16 08:26  嘒彼小星  阅读(219)  评论(0编辑  收藏  举报