CodeForces 489F dp[][]
将每列0和1数目切出来然后根据组合数来dp一直推到dp[0][0],即列有0个1的木有了,列有1个1的木有了==
1 #include<stdio.h> 2 #include<string.h> 3 long long dp[505][505],x[505][505]; 4 int main() 5 { 6 int n,m,i,cnt0,cnt1,cnt,j; 7 long long MOD; 8 scanf("%d%d%I64d",&n,&m,&MOD); 9 cnt0=cnt1=0; 10 for (i=1;i<=m;i++) 11 for (j=1;j<=n;j++) scanf("%1d",&x[i][j]); 12 for (i=1;i<=n;i++) 13 { 14 cnt=0; 15 for (j=1;j<=m;j++) 16 cnt+=x[j][i]; 17 if (cnt==0) cnt0++; 18 else if (cnt==1) cnt1++; 19 } 20 // printf("%d %d\n",cnt0,cnt1); 21 memset(dp,0,sizeof(dp)); 22 dp[cnt0][cnt1]=1; 23 for (i=cnt0;i>=0;i--) 24 for (j=n;j>=0;j--) 25 if (!dp[i][j]){ 26 if (j>=2) dp[i][j]=(dp[i][j]+dp[i+2][j-2]*((i+2)*(i+1)/2%MOD)%MOD)%MOD; 27 if (j>=1) dp[i][j]=(dp[i][j]+dp[i+1][j]*((i+1)*j%MOD)%MOD)%MOD; 28 dp[i][j]=(dp[i][j]+dp[i][j+2]*((j+2)*(j+1)/2%MOD)%MOD)%MOD; 29 } 30 printf("%I64d\n",dp[0][0]); 31 }