D

D - Cheerleaders

题目链接:https://vjudge.net/contest/154063#problem/D

题目大意:

    给你一个 nm 的方格,现在有 k 个相同石子,我们要将这 k 个石子完全放入 nm 中,

要求的是第一行、第一列、最后一行和最后一列中必须有石子,求的是方案数。

解题思路: 
我们来分析一下这个题目,因为题目中要求的是第一行、第一列、最后一行和最后一列中必须有石子,那么我们现在应该从反面考虑也就是利用容斥原理解决这个问题,这个是很容易想到的,那么现在我们设 4 个事件: 
A 
B 
C 
D 
那么我们要求的方案数就是: 
|ABCD|=|A|+|B|+|C|+|D||AB||AC||AD||BC||BD||CD|+|ABC|+|ABD|+|ACD|+|BCD||ABCD|
然后利用二进制枚举总的状态就可以了。

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int MOD=1000007;
const int MAX=505;
int c[MAX][MAX];
void plzh()
{
    for(int i=0;i<=500;i++)
      {
           c[i][0]=1;
          c[i][i]=1;
      }
    for(int i=2; i<=500; i++)
    {
        for(int j=1; j<i; j++)
        {
            c[i][j]=(c[i-1][j-1]+c[i-1][j])%MOD;
        }
    }
}
int main()
{
    plzh();
    int t,s=0;
    int n,m,k;
    scanf("%d",&t);
    while(t--)
    {
        s++;
        scanf("%d%d%d",&n,&m,&k);
        int sum=0;
        for(int i=0; i<16; i++)
        {
            int x=n,y=m,cnt=0;
            if(i&1)
            {
                x--;
                cnt++;
            }
            if(i&2)
            {
                y--;
                cnt++;
            }
            if(i&4)
            {
                x--;
                cnt++;
            }
            if(i&8)
            {
                y--;
                cnt++;
            }
            if(cnt&1)
                sum= ((sum - c[x*y][k])%MOD+MOD)%MOD;
            else   sum=(sum+c[x*y][k])%MOD;
        }
        printf("Case %d: %d
",s,sum);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/fenhong/p/6574540.html