POJ 3254 Corn Fields

来源:互联网 发布:dwg mac 编辑:程序博客网 时间:2024/06/05 03:06

poj.org/problem?id=3254

采用二进制的数据表示每个方格种还是不种,然后化为十进制记录不同的状态,dp[n][m]代表第n行的第m中状态一个出现的方案个数,对于m的状态,要判断是否可以存在,并且是否有两个草地相邻,是否和第n-1行的的某种状态的草地相邻,如果相邻的话就舍弃!

#include <stdio.h>#include <string.h>#include <iostream>#include <algorithm>using namespace std;const int N = 12;const int mod = 100000000;int m,n;int dp[N][1<<N],save[N];bool CheckRow(int x){///判断是否有相邻的1    if(x & x << 1)  return false;    return true;}bool CheckColumn(int x, int y){///判断两个数是否在相同位置有1    if(x & y)   return false;    return true;}int main(){//    freopen("in.txt", "r", stdin);    while(scanf("%d%d",&m,&n) == 2){        memset(dp, 0, sizeof(dp));        memset(save, 0, sizeof(save));        for(int i=0; i<m; i++){            for(int j=0; j<n; j++){                int tmp;                scanf("%d",&tmp);                if(tmp) save[i] = save[i] | (1 << j);///用二进制记录一行的信息            }        }        for(int i=0; i<(1 << n); i++)///初始化第0行            if((save[0] | i) == save[0] && CheckRow(i))                dp[0][i] = 1;        for(int i=1; i<m; i++)          for(int j=0; j<(1 << n); j++)                if(CheckRow(j) && (save[i] | j) == save[i])                    for(int k=0; k<(1 << n); k++)                        if(CheckColumn(j, k))                            dp[i][j] = (dp[i][j] + dp[i-1][k]) % mod;        int ans = 0;        for(int i=0; i<(1 << n); i++)            ans = (ans + dp[m-1][i]) % mod;        printf("%d\n",ans);    }    return 0;}



0 0