zoukankan      html  css  js  c++  java
  • poj

    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
    ", 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
    ",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
    ",ans);
    104     }
    105     return 0;
    106 }
  • 相关阅读:
    tftp服务、串口工具minicom
    意外的“黄金点”
    软件工程实践总结
    关于 K米 —— 的案例分析
    关于git的学习
    第二次作业_需求分析与原型设计
    安装appium
    淘宝
    Selenium API基础 8种定位
    selenium
  • 原文地址:https://www.cnblogs.com/nowandforever/p/4713997.html
Copyright © 2011-2022 走看看