https://www.luogu.org/problemnew/show/P1879
分析
数据已经提醒是状压了
我们考虑f[i][j]表示第i行状态为j时的方案数
则我们从f[i-1][k]转移,只需要考虑j和k是否有相邻位,j和k是否满足草地的状况即可
#include <iostream> #include <cstdio> #include <memory.h> using namespace std; typedef long long ll; const ll P=1e9; const int N=1<<12; ll f[2][N]; bool b[N]; int gss[2]; int n,m,mxb; int main() { scanf("%d%d",&n,&m);mxb=1<<m; f[0][0]=1; for (int i=0;i<mxb;i++) if (!(i&(i>>1))&&!(i&(i<<1))) b[i]=1; for (int i=1;i<=n;i++) { gss[i&1]=0;memset(f[i&1],0,sizeof f[i&1]); for (int j=1,k;j<=m;j++) scanf("%d",&k),gss[i&1]=(gss[i&1]<<1)+k; for (int j=0;j<mxb;j++) if (b[j]&&(gss[i&1]&j)==j) for (int k=0;k<mxb;k++) if (b[k]&&(gss[(i-1)&1]&k)==k&&!(k&j)) (f[i&1][j]+=f[(i-1)&1][k])%=P; } ll ans=0; for (int i=0;i<mxb;i++) if (b[i]&&(gss[n&1]&i)==i) (ans+=f[n&1][i])%=P; printf("%lld",ans); }