题目:
http://poj.org/problem?id=3254
题解:
把一行压成一个状态
这样枚举每行,枚举这行和上行的状态,判断合法然后转移
#include<cstdio> #include<algorithm> #include<cstring> #include<cmath> #define N 15 typedef long long ll; using namespace std; ll m,n,f[N][1<<N],a[N][N],poss[N],t,ans; inline bool ok(ll a,ll b) { for (int i=N;i>=0;i--) if (!(a&(1<<i)) && (b&(1<<i))!=0 ) return 0; if (b & (b<<1)) return 0; return 1; } int main() { scanf("%lld%lld",&n,&m);t=1<<m; for (int i=1;i<=n;i++) for (int j=0;j<m;j++) { scanf("%lld",&a[i][j]); if (a[i][j]==1) poss[i]+=(1<<j); } f[0][0]=1; for (int i=1;i<=n;i++) for (int j=0;j<t;j++) if (ok(poss[i],j)) for (int k=0;k<t;k++) if ((j&k)==0) f[i][j]+=f[i-1][k]; for (int i=0;i<t;i++) ans+=f[n][i]; printf("%lld\n",ans%100000000); return 0; }