P1879 [USACO06NOV]玉米田Corn Fields

#include<cstdio>
#include<algorithm>
using namespace std;
const int N=14;
const int mol=100000000; 
int n,m,pos[N][N],env[N],dp[N][1<<N];//envoriment & situation
bool can[1<<N];// 判断状态是否合法 
template <typename e> inline void read(e &x)
{
    x=0;int f=1;char ch=getchar();
    while(ch<'0' || ch>'9') {if(ch=='-') f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9') {x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
    x*=f;    
}
int main()
{
    read(n);read(m);register int i,j,k;
    for(i=1;i<=n;++i)
    for(j=1;j<=m;++j)
          read(pos[i][j]),env[i]=(env[i]<<1)+pos[i][j]; // solve the environment problems 
    int mx=(1<<m)-1;//最大的状态就是每一块都种上草
    for(i=0;i<=mx;++i) if((((i<<1)&i)==0)&(((i>>1)&i)==0)) can[i]=1;//判断合法 没有相邻即为合法
    for(i=0;i<=mx;++i) if((can[i])&((i&env[1])==i)) dp[1][i]=1; //先处理第一排 because每一排都是由上排转移过来的 
    for(i=2;i<=n;++i) // 枚举其余行 
    for(j=0;j<=mx;++j)  
    if((can[j])&(j&env[i])==j) //判断j状态是否可行并且符合environment 
    for(k=0;k<=mx;++k)
    if((j&k)==0) //如果两者没有相邻的地方,合法 
       dp[i][j]=(dp[i][j]+dp[i-1][k])%mol;
    long long ans=0;
    for(i=0;i<=mx;++i) ans=(ans+dp[n][i])%mol;
    printf("%lld",ans);
    return 0;
}

 

posted @ 2019-10-24 20:00  sooner  阅读(37)  评论(0编辑  收藏  举报