Cheerleaders UVA - 11806 数学思维题
题意:
m行n列的矩形网格里放置k个相同的石子,所有石子都要用完,第一行,第一列,最后一行,最后一列都必须有棋子,一共有多少种合法的方案数。
输入T<=50,后面T行每行输入M、N、K(2<=m,n<=20)(k<=500)
输出方案数对1000007取模后的结果。
分析:
求出
第一行没有石子的方案数A
最后一行没有石子的方案数B
第一列没有石子的方案数C
最后一列没有石子的方案数D
用k个任意在网格放的方案数为S
那么只需要求S中不存在ABCD的方案数。
对此的话只需要容斥一下就能处理出来。
附上AC代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int t;
int m,n,k;
const int maxn=5e2+10;
const int mod=1e6+7;
int c[maxn+10][maxn+10];
void init()
{
memset(c,0,sizeof(c));
c[0][0]=1;
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()
{
init();
cin>>t;
for(int zz=1;zz<=t;zz++){
cin>>n>>m>>k;
int sum=0;
for(int i=0;i<16;i++){
int b=0,r=n,q=m;
if(i&1)
r--,b++;
if(i&2)
r--,b++;
if(i&4)
q--,b++;
if(i&8)
q--,b++;
if(b&1)
sum=(sum+mod-c[r*q][k])%mod;
else
sum=(sum+c[r*q][k])%mod;
}
cout<<"Case "<<zz<<": "<<sum<<endl;
}
return 0;
}