计算一个n*m的格子放k个球的方案数,要求第一行,第一列,最后一行,最后一列,都要有球。
直接计算显然是由点复杂,根据容斥原理,先求逆问题,也就是:第一行有球||第一列有球||最后一行有球||最后一列有球。这些都比较好求,然后用总数减去就是答案。
#include<iostream> #include<math.h> #include<stdio.h> #include<algorithm> #include<string.h> #include<vector> #include<queue> #include<map> #include<set> using namespace std; #define B(x) (1<<(x)) void cmax(int& a,int b){ if(b>a)a=b; } void cmin(int& a,int b){ if(b<a)a=b; } typedef long long ll; const int oo=0x3f3f3f3f; const ll OO=1LL<<61; const int MOD=1000007; const int maxn=550; int C[maxn][maxn]; void Init(){ memset(C,0,sizeof C); for(int i=0;i<maxn;i++){ C[i][0]=C[i][i]=1; for(int j=0;j<i;j++){ C[i][j]=(C[i-1][j]+C[i-1][j-1])%MOD; } } } int main(){ //freopen("E:\\read.txt","r",stdin); int T,m,n,k,t1,t2,t3,t4,ans; scanf("%d",&T); Init(); for(int cas=1;cas<=T;cas++){ scanf("%d %d %d",&n,&m,&k); t1=(2*C[(n-1)*m][k]+2*C[n*(m-1)][k])%MOD; t2=(4*C[(n-1)*(m-1)][k]+C[(n-2)*m][k]+C[n*(m-2)][k])%MOD; t3=(2*C[(n-2)*(m-1)][k]+2*C[(n-1)*(m-2)][k])%MOD; t4=C[(n-2)*(m-2)][k]; ans=(t1-t2+MOD)%MOD; ans=(ans+t3)%MOD; ans=(ans-t4+MOD)%MOD; ans=(C[n*m][k]-ans+MOD)%MOD; printf("Case %d: %d\n",cas,ans); } return 0; }