[USACO06NOV]玉米田Corn Fields

题面描述

状压dp。

(f[i][sta])为第(i)层状态为(sta)的方案数。

然后每次可以枚举上一层的状态以及本层的状态,然后如果不冲突且满足地图的要求,则转移。

时间复杂度(O(2^{2m}*n*m)).

然而过不了...大了一点点。考虑对于每一层预处理出哪些状态可行,可以省掉(O(m))的枚举。

时间复杂度(O(2^{2m}*n)).

#pragma GCC optimize(3)
#include<bits/stdc++.h>
using namespace std;
void read(int &x){
    x=0;int f=1;char ch=getchar();
    for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-f;
    for(;isdigit(ch);ch=getchar()) x=(x<<1)+(x<<3)+ch-'0';x*=f;
}
#define write(x) printf("%d
",x)
const int mod = 1e8;
int f[(1<<12)+10][2],n,m,mp[13][13],vis[(1<<12)+10][2];
void print(int x) {
    char s[10];
    //(x, s, 2);printf("%s
",s);
}
int main(){
    read(n),read(m);for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) read(mp[i][j]);
    for(int i=1;i<=n;i++) {
        for(int s=0;s<(1<<m);s++) {
            int bo=1;
            for(int j=1;j<=m;j++) if((s&(1<<(j-1)))&&!mp[i][j]) bo=0;
            for(int j=1;j<m;j++) if((s&(1<<j))&&(s&(1<<(j-1)))) bo=0;
            vis[s][i&1]=bo;f[s][i&1]=0;
        }
        if(i==1) {for(int s=0;s<(1<<m);s++) f[s][1]=vis[s][1];continue;}
        for(int s1=0;s1<(1<<m);s1++)
            for(int s2=0;s2<(1<<m);s2++)
                if((!(s1&s2))&&vis[s1][(i&1)^1]&&vis[s2][i&1])
                    (f[s2][i&1]+=f[s1][(i&1)^1])%=mod;
    }int ans=0;
    for(int s=0;s<(1<<m);s++) ans=(ans+f[s][n&1])%mod;
    //write(f[0][0]),write(f[2][0]);
    return write(ans),0;
}

原文地址:https://www.cnblogs.com/hbyer/p/9839665.html