首页 > 代码库 > POJ 3254 Corn Fields(状态压缩DP)

POJ 3254 Corn Fields(状态压缩DP)

状态压缩DP,注意不能选的地方和不挨着对本行一个意思,本行自己选的是另一个意思。可相邻与范围限制不同。



#include<algorithm>
#include<iostream>
#include<iterator>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<map>
#define inf (1<<30)
#define MOD 100000000
using namespace std;
typedef long long ll;
const int maxn=10+100;
ll dp[2][1<<14];
int vis[1<<14];
ll add;
int in[14];
int N,M;
int cp;
void dfs(int r,int c,int cur)
{
    if(cur==M)
        {dp[r][c]=(dp[r][c]+add)%MOD;return;}
    dfs(r,c,cur+1);
    if(cur<=M-1 && !((1<<cur)&c))
    {
        if(((1<<cur)&cp)) return;
        if(cur==0)
        {
            if(!((1<<cur+1)&c))
                dfs(r,c| (1<<cur),cur+1);
        }
        else if(cur==M-1)
        {
            if(!((1<<cur-1)&c))
                dfs(r,c|(1<<cur),cur+1);
        }
        else if(!((1<<cur+1)&c) && !((1<<cur-1)&c))
            dfs(r,c | (1<<cur) ,cur+2);
    }

}//处理好自己的位置就行,之前用while错了
int main()
{
    while(~scanf("%d%d",&N,&M))
    {
        int rt=(1<<M)-1;
        for(int i=0;i<N;i++)
        {
            int t=0,k;
            for(int j=0;j<M;j++)
            {
                scanf("%d",&k);
                k=1-k;
                if(k)
                    t|=1<<j;
            }
            in[i]=t;
        }
        memset(dp,0,sizeof(dp));
        add=1;cp=in[0];
        dfs(0,0,0);
        for(int i=1;i<N;i++)
        {
            memset(dp[i%2],0,sizeof(dp[0]));
            for(int j=0;j<=rt;j++)if(dp[(i-1)%2][j])
            {
                add=dp[(i-1)%2][j];
                cp=j|in[i];
                dfs(i%2,0,0);
            }
        }
        ll ans=0;
        for(int j=0;j<=rt;j++)
            ans+=dp[(N-1)%2][j],ans%=MOD;
        printf("%I64d\n",ans);
    }


    return 0;
}


POJ 3254 Corn Fields(状态压缩DP)