zoukankan      html  css  js  c++  java
  • 【状压DP】poj3254 Corn Fields

    题意: 
    一块n*m的田,1表示这个地方可以种植,0代表这个地方不能种植。植物种植还必须满足两株植物不能相邻(横竖都不行)。问共有几种种植方法,而且当什么都不种时认为是一种方法。 
    解题思路: 
    种植用1表示,不种植用0表示。每一行的情况就可以用一个二进制数state来存储。state的范围是 [0 ~ 1<< state). 
    dp[i][state]表示第i行状态为state的情况下满足条件的数目。 
    状态转移方程为:dp[i][state] += dp[i-1][pre_state];这个state和pre_state必须满足意义所给的条件,即左右不相邻,上下不相邻。那么 第i行状态为state的情况为第i-1行所有满足条件的状态为pre_state相加而成。 
    最后的答案为最后一行所有状态的情况和相加而得。

    代码如下:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    
    int dp[15][1<<15];
    bool is[15][15];
    int n,m;
    const int MOD = 1e8;
    
    bool check(int x,int state)
    {
        if((state&(state<<1))) return false;
        for(int i=1;i<=m;i++)
        {
            if(!is[x][i])
            {
                if(((1<<(m-i))& state)!=0) return false;
            }
        }
        return true;
    }
    
    int main()
    {
        while(scanf("%d%d",&n,&m)!=EOF)
        {
              memset(dp,0,sizeof(dp));
              for(int i=1;i<=n;i++) for(int j = 1;j<=m;j++) scanf("%d",&is[i][j]);
              dp[0][0]=1;
              long long ans=0;
              for(int i=1;i<=n;i++)
              {
                  for(int j=0;j<(1<<m);j++)
                  {
                      if(check(i,j)) 
                      {
                          for(int k=0;k<(1<<m);k++)
                          {
                               if(!(k&j))dp[i][j]+=dp[i-1][k];
                          }
                      }
                      if(i==n)ans=(ans+dp[i][j])%MOD;
                  }
              }
             printf("%lld
    ",ans); 
        }
        return 0;
    }
  • 相关阅读:
    webpack中设置jquery为全局对象
    JS判断不同web访问环境,主要针对移动设备,
    js比较两个日期天数差
    原生js跨域
    我们项目中用到的jsonp跨域
    Js跨域解决方法总结
    js call的使用,js call 方法实现继承
    windows下配置bower路径
    兼容弹层代码
    自定义下拉列表框(2015.1.30)
  • 原文地址:https://www.cnblogs.com/rir1715/p/6804756.html
Copyright © 2011-2022 走看看