E Cheerleaders (UVA 11806)

来源:互联网 发布:部落战争mac电脑版 编辑:程序博客网 时间:2024/06/07 06:27




题目大意:

就是给定一个 n * m 的方格,然后在这个方格中 放入k个石子有几种方法,条件限制是要求第一行,第一列,最后一行,最后一列必须有石子。

解题思路:

这个可以考虑容斥原理,就是总数减去 第一行,第一列,最后一行,最后一列 没有石子的数目,现在假设 

事件A: 第一行没有石子;

事件B: 第一列没有石子;

事件C: 最后一行没有石子;

事件D: 最后一列没有石子;

则我们需要求的方法数:= C(n*m,k) - AUBUCUD; AUBUCUD = |A| + |B| + |C| + |D| - |AB| - |BC| - |AC| - |AD| - |BD| - |CD| + |ABC| + |ABD| + |ACD| + |BCD| - |ABCD|,我们写程序的时候可以借助二进制来表示 集合,然后枚举就行了...

还要注意的是 先打一个表,将组合数打出来

My Code:

<span style="font-size:18px;">#include <iostream>#include <cstdio>#include <cstring>using namespace std;const int MAXN = 505;const int MOD = 1000007;int mat[MAXN][MAXN];void Init(){    memset(mat, 0, sizeof(mat));    mat[0][0] = 1;    for(int i=1; i<MAXN; i++)    {        mat[i][0] = mat[i][i] = 1;        for(int j=1; j<i; j++)        {            mat[i][j] = mat[i-1][j-1] + mat[i-1][j];            mat[i][j] %= MOD;        }    }}int main(){    Init();    int T, n, m, k;    cin>>T;    for(int cas=1; cas<=T; cas++)    {        cin>>n>>m>>k;        int ans = 0;        for(int i=0; i<(1<<4); i++)        {            int j = 0, r = n, c = m;            if(i & 1)            {                r--;                j++;            }            if(i & 2)            {                r--;                j++;            }            if(i & 4)            {                c--;                j++;            }            if(i & 8)            {                c--;                j++;            }            if (j & 1)                ans = (ans + MOD - mat[r*c][k])%MOD;            else                ans = (ans + mat[r*c][k])%MOD;        }        printf("Case %d: %d\n",cas,ans);    }    return 0;}</span>


0 0
原创粉丝点击