点击这里查看原题
用二进制串表示每一行的摆放情况,预处理出各个状态间的转移关系即可。
f[i][j]表示第i行按状态j摆放的方案数。
/*
User:Small
Language:C++
Problem No.:1725
*/
#include<bits/stdc++.h>
#define ll long long
#define inf 999999999
using namespace std;
const int M=(1<<12)+5,mod=1e8;
int f[13][M],n,m,c[M],tot,num[M],d[13],ans;
bool vis[M][M];
void pre(){
for(int i=0;i<(1<<m);i++){
if(i&(i>>1)) continue;
c[++tot]=i;
for(int j=i;j;j>>=1) num[tot]+=(j&1);
}
for(int i=1;i<=tot;i++)
for(int j=1;j<=tot;j++)
vis[i][j]=(c[i]&c[j])==0;
}
int main(){
freopen("data.in","r",stdin);//
scanf("%d%d",&n,&m);
pre();
for(int i=1;i<=n;i++){
int x;
for(int j=0;j<m;j++){
scanf("%d",&x);
d[i]|=x<<j;
}
}
for(int i=1;i<=tot;i++) if((c[i]&d[1])==c[i]) f[1][i]=1;
for(int i=2;i<=n;i++){
for(int j=1;j<=tot;j++){
if((c[j]&d[i])!=c[j]) continue;
for(int k=1;k<=tot;k++){
if(vis[j][k]) f[i][j]=(f[i][j]+f[i-1][k])%mod;
}
}
}
for(int j=1;j<=tot;j++) ans=(ans+f[n][j])%mod;
printf("%d\n",ans);
return 0;
}