http://poj.org/problem?id=3254

参考:http://blog.csdn.net/accry/article/details/6607703

农夫想在m*n的土地上种玉米,但是有的土地很贫瘠,所以不能种,每块土地标为1的表示能种,标为0的表示不能种,并且种玉米的土地不能相邻,

问有多少种合法的种植方案.(全部不种也算一种)

第一道状压,理解了比较久的时间.

就是用二进制的0和1代表土地种还是不种,这样每一行都可以用一个2进制数表示,列数<=12,故最多有2<<12种状态.

代表一个状态,就可以建立状态转移方程.dp[i][j]代表第i行状态为j时总的方案数,dp[i][j]=sigma(dp[i-1][j']);

判断冲突充分利用了位运算的性质,比如某个状态是否有相邻的1存在则状态x&(x>>1) 或者x&(x<<1)即可.因为等于向左或向右移动一位.

判断是否跟上一行的冲突也是一样.

用滚动数组总是写的不对,好像是初始化的问题.

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cmath>
  4 #include <vector>
  5 #include <cstring>
  6 #include <string>
  7 #include <algorithm>
  8 #include <string>
  9 #include <set>
 10 #include <functional>
 11 #include <numeric>
 12 #include <sstream>
 13 #include <stack>
 14 //#include <map>
 15 #include <queue>
 16 #include <deque>
 17 //#pragma comment(linker, "/STACK:102400000,102400000")
 18 #define CL(arr, val)    memset(arr, val, sizeof(arr))
 19
 20 #define ll long long
 21 #define INF 0x7f7f7f7f
 22 #define lc l,m,rt<<1
 23 #define rc m + 1,r,rt<<1|1
 24 #define pi acos(-1.0)
 25
 26 #define L(x)    (x) << 1
 27 #define R(x)    (x) << 1 | 1
 28 #define MID(l, r)   (l + r) >> 1
 29 #define Min(x, y)   (x) < (y) ? (x) : (y)
 30 #define Max(x, y)   (x) < (y) ? (y) : (x)
 31 #define E(x)        (1 << (x))
 32 #define iabs(x)     (x) < 0 ? -(x) : (x)
 33 #define OUT(x)  printf("%I64d\n", x)
 34 #define lowbit(x)   (x)&(-x)
 35 #define Read()  freopen("a.txt", "r", stdin)
 36 #define Write() freopen("b.txt", "w", stdout);
 37 #define maxn 110
 38 #define maxv 5010
 39 #define mod 1000000000
 40 using namespace std;
 41 int n,m,top=0;
 42 int state[600],num[110];
 43 int dp[20][600]; //最多是600个状态,不知道是以什么方式算出来的
 44 int cur[20];
 45 inline bool ok(int x) //判断同一行是否有相邻的1
 46 {
 47     if(x&x<<1) return 0;
 48     return 1;
 49 }
 50 void init() //初始化 2^m个状态,把有相邻1的状态的去掉
 51 {
 52     top=0;
 53     int total=1<<m;
 54     for(int i=0;i<total;i++)
 55         if(ok(i)) state[++top]=i;
 56 }
 57 inline bool fit(int x,int k) //判断状态x和读入的第k行是否冲突,注意cur[k]中1代表不能种,
 58 {                            //所以只要相与为1则表示不行
 59     if(x&cur[k]) return 0;
 60     return 1;
 61 }
 62 int main()
 63 {
 64     //Read();
 65     while(~scanf("%d%d",&n,&m))
 66     {
 67         init();
 68         memset(dp,0,sizeof(dp));
 69         for(int i=1;i<=n;i++)
 70         {
 71             cur[i]=0;
 72             int num;
 73             for(int j=1;j<=m;j++) //这里是为0表示可以种,为1表示是不可以种
 74             {                     //注意和上面区分,这里主要是为了判断冲突.
 75                 scanf("%d",&num);
 76                 if(!num) cur[i]+=(1<<(m-j));//把每一行转换成2进制,并用cur存储
 77             }
 78             //printf("%d\n",cur[i]);
 79         }
 80         for(int i=1;i<=top;i++) //初始化第一行,
 81         {
 82             if(fit(state[i],1)) //不冲突表示可以放
 83                 dp[1][i]=1;
 84         }
 85         for(int i=2;i<=n;i++)
 86         {
 87             for(int j=1;j<=top;j++)
 88             {
 89                 if(!fit(state[j],i)) continue; //判断第i行和读入的图是否冲突
 90                 for(int k=1;k<=top;k++)
 91                 {
 92                     if(!fit(state[k],i-1)) continue; //判断第i-1行是否冲突
 93                     if(state[j]&state[k]) continue;//判断第i行和第i-1行是否冲突
 94                     dp[i][j]=(dp[i][j]+dp[i-1][k])%mod;
 95                 }
 96             }
 97         }
 98         int ans=0;
 99         for(int i=1;i<=top;i++)
100         {
101             ans=(ans+dp[n][i])%mod;
102         }
103         printf("%d\n",ans);
104     }
105     return 0;
106 }

转载于:https://www.cnblogs.com/nowandforever/p/4713997.html

poj - 3254 Corn Fields (状态压缩dp入门)相关推荐

  1. poj 3254 Corn Fields 状态压缩dp

    Corn Fields Time Limit: 2000MS   Memory Limit: 65536K       Description Farmer John has purchased a ...

  2. poj 3254 Corn Fields (状态压缩DP)

    题目:http://poj.org/problem?id=3254 思路见代码: #include<iostream> using namespace std;const int MOD= ...

  3. POJ 3254 Corn Fields (状态压缩)

    刚开始的思路是  把0-2^x的 所有状态枚举, 然后找符合条件的,   但是 发现 当12*12 时  1的数量x 超过64  这是个庞大的数字, 跟本就没法枚举: 想到用状态压缩,  但是 怎么压 ...

  4. Poj - 3254 Corn Fields (状压DP)(入门)

    题目链接:https://vjudge.net/contest/224636#problem/G 转载于:https://blog.csdn.net/harrypoirot/article/detai ...

  5. POJ - 3254 Corn Fields(状压dp)

    题目链接:点击查看 题目大意:给出一个n*m的地图,有些位置不能放牧,然后放牧的条件是相邻两个格子不允许同时使用,问可行方案有几种 题目分析:因为给出的数据范围很小,并且放牧的状态是放或者不放,很容易 ...

  6. 状态压缩dp入门 第一题 POJ 3254 Corn Fields

    Corn Fields Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 6460   Accepted: 3436 Descr ...

  7. POJ 3254 Corn Fields [DP]

    题意:略. 思路:第一次做状态压缩的dp. 在这里说一下状态压缩的原则.因为每一行只有最多12个格子,每个格子只有1(可放牛)和0(不可放牛)两种状态,这总共是2^12种状态,直接用一个int整型变量 ...

  8. POJ - 3254 - Corn Fields

    线上题目: Corn Fields Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 6936   Accepted: 3697 ...

  9. poj3254 Corn Fields 状压DP入门

    Corn Fields Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 19368   Accepted: 10169 Des ...

最新文章

  1. 解决java前后端分离端口跨域问题
  2. 密码学系列之:Merkle–Damgård结构和长度延展攻击
  3. (*长期更新)软考网络工程师学习笔记——Section 14 Linux服务器配置
  4. Dalvik/ART(ANDROID)中的多线程机制(2)
  5. extjs5的grid垂直滚动条bug_ExtJS 6.2.1 Classic Grid 滚动条bug解决方案
  6. 阿里巴巴 连接池 druid 的使用、maven依赖
  7. java程序员必看经典书单,以及各个阶段学习建议
  8. git命令升级版用法
  9. matlab3d绘图实例,matlab各种三维绘图及实例
  10. java服务发现_【Java】Eureka – 服务发现(Server)
  11. 您如何轻松地水平居中 div 使用CSS? [重复]
  12. window下使用tail -f查看tomcat日志
  13. 【测试基础】Linux打包、解包、解压缩命令这一篇全
  14. 重回第一!没想到300w了...
  15. GHOSTXP_SP3电脑公司装机特别版 V30.0[NTFS]
  16. MIDIPLUS/迷笛studio m pro 2 valve声卡安装调试教程
  17. 生物特征识别学科发展报告
  18. 【蓝桥杯每日一练:木头加工】
  19. 腾讯T2大牛亲自教你!5214页PDF的进阶架构师学习笔记,终局之战
  20. 韩剧《天空之城》推荐

热门文章

  1. Vue视频教程系列第三十七节-子路由地配置
  2. 《最强蜗牛》运营分析:这个奇葩放置游戏的乐趣在哪里?
  3. Windows下使用zerotier时提示PORT_ERROR错误
  4. final,finally,finaliz的区别(Java)
  5. 分界符 EOF 不使用反斜杠转义的技巧
  6. ORA-27041: unable to open file--恢复被rm意外删除数据文件
  7. 小议Oracle外键约束修改行为
  8. 写存储过程与调用存储过程
  9. 【Python3_基础系列_012】Python3-异常与断言
  10. CSS公共清除浏览器默认样式