码迷,mamicode.com
首页 > 其他好文 > 详细

uva 11806 Cheerleaders(容斥)

时间:2014-09-26 12:21:51      阅读:245      评论:0      收藏:0      [点我收藏+]

标签:style   color   io   os   for   sp   问题   on   c   

题意:如何摆放拉拉队的问题,在矩形网格m*n中,k名拉拉队员,要求四周网格中each side有至少一名拉拉队员,corner有人算两边,问有多少种摆法?


思路:容斥;

c[m*n][k] -- c[(n-1)*m][k] U c[(n-1)*m][k] U c[n*(m-1)][k] U c[n*(m-1)][k]


#include<cstdio>
#include<iostream>
#include<cstring>
#define mod 1000007
using namespace std;
typedef long long LL;

//int C1[500][500];
int C[500][500];

void pre()         //递推组合C[ ][ ]
{

    memset(C,0,sizeof C);
    C[0][0]=1;

    for(int i=1;i<=400;i++)
    {
        C[i][i]=C[i][0]=1;
        for(int j=1;j<i;j++)
            C[i][j]=(C[i-1][j-1]+C[i-1][j])%mod;
    }
}

int solve(int M,int N,int k)   //容斥
{
    int sum=0;
    for(int i=1;i<(1<<4);i++) //枚举
    {
        int n=N,m=M,bits=0;
        if(i&1)
        {
            bits++;
            n--;
        }
        if(i&(1<<1))
        {
            bits++;
            m--;
        }
        if(i&(1<<2))
        {
            bits++;
            n--;
        }
        if(i&(1<<3))
        {
            bits++;
            m--;
        }
        if(bits%2==1)   //判断奇偶
            sum=(sum+C[n*m][k])%mod;
        else
            sum=(sum-C[n*m][k])%mod;
    }
    return ((C[N*M][k]-sum)%mod+mod)%mod;
}


int main()
{
    int T;
    cin>>T;
    pre();
    for(int cas=1;cas<=T;cas++)
    {
        int n,m,k;
        cin>>n>>m>>k;
        printf("Case %d: ",cas);
        if(k>n*m)
            printf("0\n");
        else
            printf("%d\n",solve(n,m,k));
    }
    return 0;
}



uva 11806 Cheerleaders(容斥)

标签:style   color   io   os   for   sp   问题   on   c   

原文地址:http://blog.csdn.net/code_or_code/article/details/39576537

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!