标签:
题意:给出m*n的网格,k个人,要求第一行,最后一行,第一列和最后一列必须有人。
思路:正难则反,考虑第一行,最后一行,第一列和最后一列都有人的要求都达不到的情况。sum=sum1-a-b-c-d+ab+ac+ad+bc+bd+cd-abc-abd-acd-bcd+abcd。sum1用0表示。a,b,c,d用1,2,4,8表示,用与运算,例:1&i若不为0则表示i含有a集合。例:11(1011)包含8,2,1,即d,b,a。
刘汝佳代码:
#include<iostream> #include<cstring> using namespace std; const int MOD=1000007; const int MAXK=500; int C[MAXK+10][MAXK+10]; int main() { memset(C,0,sizeof(C)); C[0][0]=1; for(int i=0;i<=MAXK;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 T; scanf("%d",&T); for(int kase=1;kase<=T;kase++) { int n,m,k,sum=0; scanf("%d%d%d",&n,&m,&k); for(int s=0;s<16;s++) { int b=0,r=n,c=m; if(s&1){r--;b++;} if(s&2){r--;b++;} if(s&4){c--;b++;} if(s&8){c--;b++;} if(b&1)sum=(sum+MOD-C[r*c][k])%MOD; else sum=(sum+C[r*c][k])%MOD; } printf("Case %d:%d\n",kase,sum); } return 0; }
标签:
原文地址:http://www.cnblogs.com/mu-ye/p/5448267.html