题意:$m*n:\ m,n \le 12$的牧场,有的格子不能选,相邻不能同时选,求方案数
$f[i][j]$前$i$行当前行选的集合为$j$
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> using namespace std; typedef long long ll; const int N=13,S=(1<<12)+5,P=1e8; inline int read(){ char c=getchar();int x=0,f=1; while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();} while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();} return x*f; } int m,n; int f[N][S],cant[N]; inline void mod(int &x){if(x>=P) x-=P;} int main(){ //freopen("in","r",stdin); m=read();n=read(); for(int i=1;i<=m;i++) for(int j=0;j<n;j++) if(!read()) cant[i]|=(1<<j); int All=1<<n; f[0][0]=1; for(int i=1;i<=m;i++) for(int j=0;j<All;j++) if( (j&(j<<1))==0 && (j&cant[i])==0 ) for(int k=0;k<All;k++) if( (k&(k<<1))==0 && (k&cant[i-1])==0 && (k&j)==0 ) f[i][j]+=f[i-1][k]; int ans=0; for(int j=0;j<All;j++) if( (j&(j<<1))==0 && (j&cant[m])==0 ) mod(ans+=f[m][j]); printf("%d",ans); }