poj 3465 Corn Fields 状态压缩

题目链接:http://poj.org/problem?id=3254

#include <cstdio>
#include <cstring>
#include <iostream>
#include <cmath>
#include <algorithm>
#include <queue>
#include <vector>
using namespace std;
const int moder = 1e8;
const int maxe = 50000;
const int maxn = 13;
const int INF  = 0x3f3f3f;

int dp[maxn][1<<maxn];
//dp[i][state] 表示第i行的state这个状态方案个数。dp[i][j] += dp[i-1][j']; 这里需要列举完所有可能的状态j'能退出j。
int G[maxn];

bool isok(int x){  //判断x是否有相邻的。
    if(x & (x<<1))   return false;
    return true;
}

int main()
{
    //freopen("E:\\acm\\input.txt","r",stdin);
    int M,N;
    cin>>M>>N;
    for(int i=1;i<=M;i++){
        G[i] = 0;
        for(int j=0;j<N;j++){
            int a;
            scanf("%d",&a);
            if(a)   G[i] |= (1<<j);
        }
    }
    G[0] = 0;
    memset(dp,0,sizeof(dp));
    dp[0][0] = 1;
    for(int i=1;i<=M;i++){                //i指向操作的行。
        for(int upstate=0;upstate<(1<<N);upstate++)
            if(isok(upstate)){
                if(dp[i-1][upstate])
                    for(int nowstate=0;nowstate<(1<<N);nowstate++){   //printf("%d\n",nowstate);
                        if(!isok(nowstate))     continue;
                        if(nowstate & upstate)  continue;    //upstate有1的地方nowstate决不允许有1.
                        if(nowstate & (~G[i]))  continue;    //G[i] 有0的地方nowstate决不允许有1.
                        dp[i][nowstate] += dp[i-1][upstate];
                    }
    }}
    int ans = 0;
    for(int i=0;i<(1<<N);i++){
        if(!isok(i))  continue;
        ans = (ans + dp[M][i])%moder;
    }
    printf("%d\n",ans);
}
View Code

 

posted @ 2013-08-26 22:21  等待最好的两个人  阅读(267)  评论(0编辑  收藏  举报