zoukankan      html  css  js  c++  java
  • POJ 3254 Corn Fields(状压DP)

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

    【题目大意】

      给出一个n*m的地图,0表示不能放,问往格子上摆放上下左右不能相邻的棋子有几种方案。

    【题解】

      首先预处理出单行合法的情况和地图中有障碍的状态,
      每次计算一行的方案时,我们枚举两种合法状态,  
      如果两种状态可以上下相邻则累加上一行该状态的答案。
      然后累计最后一行每种状态下的答案即可.

    【代码】

    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    using namespace std;
    const int N=15,M=1<<N,mod=100000000;
    int st[M],mp[M],dp[N][M],n,m,x;
    int main(){
        while(~scanf("%d%d",&n,&m)){
            memset(st,0,sizeof(st));
            memset(mp,0,sizeof(mp));
            memset(dp,0,sizeof(dp));
            for(int i=1;i<=n;i++){
                for(int j=1;j<=m;j++){
                    scanf("%d",&x);
                    if(!x)mp[i]|=(1<<(j-1));
                }
            }int cnt=0;
            for(int i=0;i<(1<<m);i++){
                if(!(i&(i<<1)))st[cnt++]=i;
            }for(int i=0;i<cnt;i++){
                if(!(mp[1]&st[i]))dp[1][i]=1;
            }for(int i=2;i<=n;i++){
                for(int j=0;j<cnt;j++){
                    if(mp[i]&st[j])continue;
                    for(int u=0;u<cnt;u++){
                        if(mp[i-1]&st[u])continue;
                        if(!(st[j]&st[u]))dp[i][j]=(dp[i][j]+dp[i-1][u])%mod;
                    }
                }
            }int ans=0;
            for(int i=0;i<cnt;i++)ans=(ans+dp[n][i])%mod;
            printf("%d
    ",ans);
        }return 0;
    }
  • 相关阅读:
    简历的快速复制
    使用stringstream对象简化类型转换
    猴子吃桃
    new和delete运算符
    绘制正余弦曲线
    计算学生的平均成绩
    判断是否为回文字符串
    统计各种字符个数
    验证用户名
    回溯法(挑战编程)
  • 原文地址:https://www.cnblogs.com/forever97/p/poj3254.html
Copyright © 2011-2022 走看看