zoukankan      html  css  js  c++  java
  • POJ 3254 Corn Fields

    题意:在m*n的矩阵上,1表示能放牛,0表示不能放。要求放的牛不能相邻(上下相邻或者左右相领),问放牛的方法种数。

    解法:设d[i][j]表示第i行状态为j的情况下,能放的牛的数量。d[i][j] += d[i-1][k],其中k表示能转移到j的状态,num(j)表示状态为j的行所放的牛的数量。当然,还要判断一下状态j是不是能放在第i行。

    tag:状压dp

     1 /*
     2  * Author:  Plumrain
     3  * Created Time:  2013-11-18 23:37
     4  * File Name: DP-POJ-3254.cpp
     5  */
     6 #include <iostream>
     7 #include <cstdio>
     8 #include <cstring>
     9 
    10 using namespace std;
    11 
    12 #define CLR(x) memset(x, 0, sizeof(x))
    13 const int mod = 100000000;
    14 
    15 int n, m, a[20][20];
    16 int d[20][1<<13];
    17 
    18 void init()
    19 {
    20     for (int i = 0; i < n; ++ i)
    21         for (int j = 0; j < m; ++ j)
    22             scanf ("%d", &a[i][j]);
    23 }
    24 
    25 bool gao1(int sta)
    26 {
    27     int x = 0;
    28     while (sta > 0){
    29         if (x == 1 && (sta&1))
    30             return 0;
    31         x = sta & 1;
    32         sta >>= 1;
    33     }
    34     return 1; 
    35 }
    36 
    37 bool gao2(int sta, int k)
    38 {
    39     for (int i = 0; i < m; ++ i)
    40         if (!a[k][i] && (sta & (1<<i))) return 0;
    41     return 1;
    42 }
    43 
    44 bool gao3(int s1, int s2)
    45 {
    46     for (int i = 0; i < (1<<m); ++ i){
    47         int t1 = s1 & (1<<i), t2 = s2 & (1<<i);
    48         if (t1 && t2) return 0;
    49     }
    50     return 1;
    51 }
    52 
    53 int DP()
    54 {
    55     CLR (d);
    56     for (int i = 0; i < (1<<m); ++ i) 
    57         if (gao1(i) && gao2(i, 0)) d[0][i] = 1;
    58 
    59     for (int i = 1; i < n; ++ i)
    60         for (int j = 0; j < (1<<m); ++ j){
    61             d[i][j] = 0;
    62             if (gao1(j) && gao2(j, i))
    63                 for (int k = 0; k < (1<<m); ++ k)
    64                     if (gao3(j, k)) d[i][j] = (d[i][j] + d[i-1][k]) % mod;
    65         }
    66 
    67     int ret = 0;
    68     for (int i = 0; i < (1<<m); ++ i)
    69         if (gao1(i) && gao2(i, n-1)) ret = (d[n-1][i] + ret) % mod;
    70     return (int)ret;
    71 }
    72 
    73 int main()
    74 {
    75     while (scanf ("%d%d", &n, &m) != EOF){    
    76         init();
    77         printf ("%d
    ", DP());
    78     }
    79     return 0;
    80 }
    View Code
    ------------------------------------------------------------------
    现在的你,在干什么呢?
    你是不是还记得,你说你想成为岩哥那样的人。
  • 相关阅读:
    Android 动画-alpha(渐变透明度动画效果)
    Memento(备忘录)
    Mediator(中介者)
    Iterator(迭代器)
    Command(命令)
    Chain of Responsibility(责任链)
    Template Method(模板方法)
    Interpreter(解释器)
    Proxy(代理)
    Flyweight(享元)
  • 原文地址:https://www.cnblogs.com/plumrain/p/POJ_3254.html
Copyright © 2011-2022 走看看