uva11806(容斥原理)

11806 - Cheerleaders

Time limit: 2.000 seconds

In most professional sporting events, cheerleaders play a major role in entertaining the spectators. Their roles are substantial during breaks and prior to start of play. The world cup soccer is no exception. Usually the cheerleaders form a group and perform at the centre of the field. In addition to this group, some of them are placed outside the side line so they are closer to the spectators. The organizers would like to ensure that at least one cheerleader is located on each of the four sides. For this problem, we will model the playing ground as an M*N rectangular grid. The constraints for placing cheerleaders are described below:

  • There should be at least one cheerleader on each of the four sides. Note that, placing a cheerleader on a corner cell would cover two sides simultaneously.
  • There can be at most one cheerleader in a cell.
  • All the cheerleaders available must be assigned to a cell. That is, none of them can be left out.

The organizers would like to know, how many ways they can place the cheerleaders while maintaining the above constraints. Two placements are different, if there is at least one cell which contains a cheerleader in one of the placement but not in the other.

Input

 

The first line of input contains a positive integer T<=50, which denotes the number of test cases. T lines then follow each describing one test case. Each case consists of three nonnegative integers, 2<=M, N<=20 and K<=500. Here M is the number of rows and N is the number of columns in the grid. K denotes the number of cheerleaders that must be assigned to the cells in the grid.

 

Output

For each case of input, there will be one line of output. It will first contain the case number followed by the number of ways to place the cheerleaders as described earlier. Look at the sample output for exact formatting. Note that, the numbers can be arbitrarily large. Therefore you must output the answers modulo 1000007.


Sample Input


Sample Output


2

2 2 1

2 3 2


Case 1: 0

Case 2: 2

 

直接分类讨论所有情况很麻烦,容易出错。那么正难则反,用容斥原理做就很简单了。

思路很好想,关键是写法。我觉得还是大白书上的用二进制来表示状态的写法最简明易懂。

我学习着写了一发,AC了。但是我觉得原书每次计算ans时没有考虑当少了几行或几列有可能不够把k个都放进去了,我加了个判断语句,当然对于uva上的数据,不加这个判断也是可以AC的。

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<map>
#include<set>
#include<vector>
#include<algorithm>
#include<stack>
#include<queue>
using namespace std;
#define INF 1000000000
#define eps 1e-8
#define pii pair<int,int>
#define LL long long int
int T,n,m,k,ans;
const int mod=1000007;
int C[505][505];
int main()
{
    //freopen("in6.txt","r",stdin);
    //freopen("out.txt","w",stdout);
    for(int i=0;i<=500;i++) C[i][0]=C[i][i]=1;
    for(int i=2;i<=500;i++)
    {
        for(int j=1;j<=i-1;j++)
        {
            C[i][j]=(C[i-1][j]+C[i-1][j-1])%mod;
        }
    }
    scanf("%d",&T);
    for(int cas=1;cas<=T;cas++)
    {
        scanf("%d%d%d",&m,&n,&k);//m*n
        ans=0;
        for(int i=0;i<16;i++)
        {
            int row=m,col=n,b=0;
            if(i&1){row--;b++;}
            if(i&2){row--;b++;}
            if(i&4){col--;b++;}
            if(i&8){col--;b++;}
            if(b&1)//b is a odd.
            {
                if(col*row>=k)
                ans=(ans-C[col*row][k]+mod)%mod;
            }
            else
            {
                if(col*row>=k)
                ans=(ans+C[col*row][k])%mod;
            }
        }
        printf("Case %d: %d\n",cas,ans);
    }
    //fclose(stdin);
    //fclose(stdout);
    return 0;
}
时间: 2024-08-24 20:42:23

uva11806(容斥原理)的相关文章

uva11806(容斥原理)

题目连接:UVA - 11806 1 #include<cstdio> 2 #include<cstring> 3 const int maxn=520; 4 const int mod=1e6+7; 5 int C[maxn][maxn]; 6 7 void init() 8 { 9 C[0][0]=1; 10 for(int i=1;i<=maxn;i++) 11 { 12 C[i][0]=C[i][i]=1; 13 for(int j=1;j<i;j++) 14

UVa 11806 拉拉队(容斥原理)

https://vjudge.net/problem/UVA-11806 题意: 在一个m行n列的矩形网格里放k个相同的石子,有多少种方法?每个格子最多放一个石子,所有石子都要用完,并且第一行.最后一行.第一列.最后一列都得有石子. 思路: 如果考虑各种情况的话很复杂,设满足第一行没有石子的方案集为A,最后一行没有石子的方案集为B,第一列没有石子的方案集为C,最后一列没有石子的方案集为D,全集为S. 一个容斥原理的公式就可以解答出来,用二进制来枚举方案集的组合. 1 #include <iost

UVA 11014 - Make a Crystal(容斥原理)

UVA 11014 - Make a Crystal 题目链接 题意:给定一个NxNxN的正方体,求出最多能选几个整数点.使得随意两点PQ不会使PQO共线. 思路:利用容斥原理,设f(k)为点(x, y, z)三点都为k的倍数的点的个数(要扣掉一个原点O).那么全部点就是f(1),之后要去除掉共线的,就是扣掉f(2), f(3), f(5)..f(n).n为素数.由于这些素数中包括了合数的情况,而且这些点必定与f(1)除去这些点以外的点共线,所以扣掉.可是扣掉后会扣掉一些反复的.比方f(6)在f

BZOJ3198 SDOI2013 spring HASH+容斥原理

题意:给定6个长度为n的数列,求有多少个数对(i,j)((i,j)≡(j,i))使得i和j位置恰好有K个数相同,其中0≤K≤6 题解: 设fi=至少有K个数相同的位置对的数量,用2^6枚举每一种可能,根据容斥原理,答案就是\[\sum\limits_{i = K}^N {{f_i}C_i^K{{\left( { - 1} \right)}^{i - K}}} \] 至于多乘一个组合数,是因为当前枚举到有x个数相同,一个位置对有i个相同的数,那么累计的时候就会算成$C_x^i$,因此实际上这个位置

UVa11806 Cheerleaders

容斥问题 考虑上下左右四个边界只满足其中1/2/3/4个边界有人的情况,可以用组合数算. 总共只有16种情况. 可以用容斥原理求解. 1 /*by SilverN*/ 2 #include<algorithm> 3 #include<iostream> 4 #include<cstring> 5 #include<cstdio> 6 #include<cmath> 7 #include<vector> 8 using namespac

hdu 4790 Just Random 容斥原理+数学

Just Random Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1723    Accepted Submission(s): 483 Problem Description Coach Pang and Uncle Yang both love numbers. Every morning they play a game w

[BZOJ 1042] 硬币购物 容斥原理

题意 有四种货币, 它们的价值分别是 c[0], c[1], c[2], c[3] . n 次询问, 每次给定 d[0], d[1], d[2], d[3], s, 问凑出 s , 且第 i 种货币不超过 c[i] 个的方案数. c[i], d[i], s <= 100000 , n <= 1000 . 分析 设第 i 种货币取了 x[i] 个. 问题转化为求不定方程 c[0]x[0] + c[1]x[1] + c[2]x[2] + c[3]x[3] = s 的非负整数解的个数. 且满足 4

HDU - 4135 Co-prime(容斥原理)

Question 参考 题意找出[a,b]中与n互质的数的个数分析通常我们求1-n中与n互质的数的个数都是用欧拉函数.但如果n比较大或者是求1-m中与n互质的数的个数等等问题,要想时间效率高的话还是用容斥原理.先对n分解质因数,分别记录每个质因数, 那么所求区间内与某个质因数不互质的个数就是 m/r(i),假设r(i)是r的某个质因子 假设只有三个质因子, 总的不互质的个数应该为p1+p2+p3-p1*p2-p1*p3-p2*p3+p1*p2*p3. pi代表m/r(i),即与某个质因子不互质的

容斥原理

对容斥原理的描述 容斥原理是一种重要的组合数学方法,可以让你求解任意大小的集合,或者计算复合事件的概率. 描述 容斥原理可以描述如下: 要计算几个集合并集的大小,我们要先将所有单个集合的大小计算出来,然后减去所有两个集合相交的部分,再加回所有三个集合相交的部分,再减去所有四个集合相交的部分,依此类推,一直计算到所有集合相交的部分. 关于集合的原理公式 上述描述的公式形式可以表示如下:                  它可以写得更简洁一些,我们将B作为所有Ai的集合,那么容斥原理就变成了: 这个