[状压DP]luogu P1879 玉米田

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);
}
View Code
在日渐沉没的世界里,我发现了你。
原文地址:https://www.cnblogs.com/mastervan/p/11136106.html