您的位置:首页 > 其它

E Cheerleaders (UVA 11806)

2016-04-02 17:15 197 查看
题目大意:

就是给定一个 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>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: