RT,思路大概是把所有不考虑贫瘠的情况的状态全部处理出来。
然后合法的话就看处理出来的状态 sta 是不是当前行的状态 yard 的子集。
fi,j 表示的是考虑第 i 行,扫描到编号为 j 的 状态的方案数。
调试过之后发现 yard 和 sta 这两个数组的处理都没问题,但是只有 30pts /kk
#include<bits/stdc++.h>
using namespace std;
const int si=14;
const int stasi=4096+10;
const int bitsi=4096+10;
const int p=100000000;
inline int mod(int x,int p){ return x<0?(x+p)-(((x+p)/p)*p):x-((x/p)*p);}
int n,m,cnt=0;
int f[si][stasi];
int sta[stasi];
int yard[si];
inline void init(int n){
for(register int i=0;i<=n;++i){
if((i&(i<<1))!=0 || (i&(i>>1))!=0) continue;
sta[++cnt]=i;
// printf("%d\n",sta[cnt]);
}
}
inline bool valid(int l,int s){
if(!((yard[l]&sta[s])==sta[s])) return false;
return true;
}
int main(){
memset(f,0,sizeof f);
scanf("%d%d",&n,&m);
for(register int i=1;i<=n;++i){
for(register int j=1,k;j<=m;++j){
scanf("%1d",&k);
if(k) yard[i]+=(1<<(m-j));
}
// printf("%d\n",yard[i]);
}
init((1<<m)-1);
for(register int i=1;i<=cnt;++i){
f[1][i]=mod(1,p);
}
for(register int i=2;i<=n;++i){
for(register int j=1;j<=cnt;++j){
if(!valid(i,j)) continue;
for(register int k=1;k<=cnt;++k){
if((sta[j]&sta[k])!=0) continue;
f[i][j]=mod(f[i][j]+f[i-1][k],p);
}
}
}
int res=0;
for(register int i=1;i<=cnt;++i){
res=mod(res+f[n][i],p);
}
return printf("%d\n",mod(res,p)),0;
}