标签: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;
}
标签:style color io os for sp 问题 on c
原文地址:http://blog.csdn.net/code_or_code/article/details/39576537