您的位置:首页 > 其它

UVa 11806 拉拉队(容斥原理)

2017-04-15 21:16 155 查看
https://vjudge.net/problem/UVA-11806

题意:

在一个m行n列的矩形网格里放k个相同的石子,有多少种方法?每个格子最多放一个石子,所有石子都要用完,并且第一行、最后一行、第一列、最后一列都得有石子。

思路:

如果考虑各种情况的话很复杂,设满足第一行没有石子的方案集为A,最后一行没有石子的方案集为B,第一列没有石子的方案集为C,最后一列没有石子的方案集为D,全集为S。

一个容斥原理的公式就可以解答出来,用二进制来枚举方案集的组合。

#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
#include <cmath>
using namespace std;

const int mod = 1000007;
const int maxn = 500+5;

int c[maxn][maxn];

void init()
{
for (int i = 0; i <= maxn; 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()
{
//freopen("D:\\input.txt", "r", stdin);
int T;
int kase = 0;
int n, m, k;
scanf("%d", &T);
init();
while (T--)
{
scanf("%d%d%d", &n, &m, &k);
int sum = 0;
for (int S = 0; S<16; S++)
{
//S=0时就相当于计算c[n*m][k],不考虑条件时的所有方法数
int b = 0, row = n, col = m;
if (S & 1)  { row--; b++; }
if (S & 2)  { row--; b++; }
if (S & 4)  { col--; b++; }
if (S & 8) { col--; b++; }
if (b & 1)   sum = (sum + mod - c[row*col][k]) % mod;
else sum = (sum + c[row*col][k]) % mod;
}
printf("Case %d: %d\n", ++kase, sum);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: