1. 程式人生 > >C - Cheerleaders

C - Cheerleaders

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 modulo1000007.

 

Sample Input

Sample Output

2

2 2 1

2 3 2

Case 1: 0

Case 2: 2

題意:給一個m*n的方格在上面放k個物體,要求第一行第一列最後一行最後一列都必須存在物體,求有多少種方案。

思路:本質上就是在m*n個人中選擇k個人的方案數,然後加了一個要求。類似於數學中的組合數,可以用楊輝三角打表。

   容斥原理二進位制列舉

設 A 為第一行沒人     

B為最後一行沒人

C為第一列沒人

D為最後一列沒人

那麼我們想要的結果      M=全集-A-B-C-D+AB+AC+AD+BC+BD+CD-BCD-ACD-ABD-ABC+ABCD

程式碼中使用1~15的二進位制把上述16種情況集合表示了。

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int MOD=1000007;
const int N=540;
int C[N][N];
void zuheshu()
{
    memset(C,0,sizeof(C));
    C[0][0]=1;


    for(int i=0; i<=500; i++)
    {
        C[i][0]=C[i][i]=1;
        for(int j=1; j<i; j++)
        {
            C[i][j]=(C[i-1][j]+C[i-1][j-1])%MOD;

        }

    }
}

int main()
{
    zuheshu();
    int t;
    cin>>t;
    for(int j=1; j<=t; j++)
    {
        int m,n,k,r,c,b;
        cin>>n>>m>>k;
        int ans=0;
        for(int i=0; i<16; i++) //用0001代表A,0010代表B,0100代表C,1000代表D
        {
            b=0;
            r=n;
            c=m;
            if(i&1)
            {
                r--;    //判斷第0位是否為1即第一行沒有人。
                b++;
            }
            if(i&2)
            {
                r--;    //判斷第1位是否為1
                b++;
            }
            if(i&4)
            {
                c--;    //判斷第2位是否為1
                b++;
            }
            if(i&8)
            {
                c--;    //判斷第3位是否為1
                b++;
            }
            if(b&1)//如果b為奇數,表示減去,若為偶數表示加上。 結果=全集-A-B-C-D+AB+AC+AD+BC+BD+CD-BCD-ACD-ABD-ABC+ABCD
            {
                ans=(ans+MOD-C[r*c][k])%MOD;
            }
            else
                ans=(ans+C[r*c][k])%MOD;
        }
        printf("Case %d: %d\n",j,ans);
    }



}