/* 限制条件 1.同行不能相邻 2.上下不能相邻 3.不能在零的地方放东西 解: 求出各行合法的状态,为第一行的和法状态赋值为1 从上到下合并状态dp[i][j]=(dp[i][j]+dp[i-1][k])%mod(其中j。k 为i和i-1行合法的状态) 也就是说把上一行的状态数目存储到dp[i][0]中了。 */ #include<stdio.h> #include<string.h> #define mod 100000000 #define N 15 int lower[N]; int ss[1<<13]; int n,m,ma[N][N],total,dp[N][700],sum[N][700];//因为len最大不超过700 int judge(int i,int j) { int k; for(k=0;k<m;k++) if((lower[k]&j)&&ma[i][k+1]==0) return 0; return 1; } void slove() { int i,j,k,len=0; memset(dp,0,sizeof(dp)); for(i=0;i<(1<<m);i++) { if(i&(i<<1))continue; ss[len++]=i; } for(i=1;i<=n;i++) for(j=0;j<len;j++) if(judge(i,ss[j]))//判断在本行合法的状态 sum[i][j]=1; for(i=0;i<len;i++) if(sum[1][i]) dp[1][i]=1; for(i=2;i<=n;i++) for(j=0;j<len;j++) { if(sum[i][j]==0)continue; for(k=0;k<len;k++){ if(sum[i-1][k]==0)continue; if(ss[j]&ss[k])continue; dp[i][j]=(dp[i][j]+dp[i-1][k])%mod; // printf("%d %d %d ",ss[j],ss[k],dp[i][j]); } } total=0; for(i=0;i<len;i++) if(sum[n][i]) total=(total+dp[n][i])%mod;//所有的状态值和 return ; } int main() { int i,j; lower[0]=1; for(i=1;i<=13;i++) lower[i]=lower[i-1]*2; while(scanf("%d%d",&n,&m)!=EOF) { for(i=1;i<=n;i++) for(j=1;j<=m;j++) scanf("%d",&ma[i][j]); slove(); printf("%d ",total); } return 0; }