zoukankan      html  css  js  c++  java
  • POJ 2411 Mondriaan's Dream

    题意:用1*2的瓷砖拼出m*n的矩形。问有多少种拼法。

    解法:设d[i][j]表示第i行状态为j的情况下,最多能有多少种拼法,对于状态j,1表示为竖着放置的瓷砖且它横跨i和i+1两行,其余皆用0表示。d[i][j] += d[i-1][k],其中k表示能转移到j的状态。

    tag:状压dp

     1 /*
     2  * Author:  Plumrain
     3  * Created Time:  2013-11-19 01:01
     4  * File Name: DP-POJ-2411.cpp
     5  */
     6 #include <iostream>
     7 #include <cstdio>
     8 #include <cstring>
     9 #include <vector>
    10 
    11 using namespace std;
    12 
    13 #define CLR(x) memset(x, 0, sizeof(x))
    14 #define PB push_back
    15 typedef long long int64;
    16 
    17 int n, m;
    18 int64 d[20][1<<12];
    19 vector<int> pat[1<<12];
    20 
    21 bool gao1(int sta)
    22 {
    23     int x = 0, time = 0;
    24     while (sta > 0){
    25         x = sta & 1;
    26         sta >>= 1;
    27         if (!x){
    28             if (time & 1) return 0;
    29             time = 0;
    30         }
    31         else ++ time;
    32     }
    33     return !(time & 1);
    34 }
    35 
    36 bool gao2(int s1, int s2)
    37 {
    38     for (int i = 0; i < m; ++ i){
    39         int t1 = s1 & (1<<i), t2 = s2 & (1<<i);
    40         if (!t1 && !t2) return 0;
    41 
    42         if (!t1) s2 ^= (1 << i);
    43     }
    44     return gao1(s2);
    45 }
    46 
    47 void init()
    48 {
    49     for (int i = 0; i < (1<<m); ++ i)
    50         pat[i].clear();
    51     for (int i = 0; i < (1<<m); ++ i)
    52         for (int j = 0; j < (1<<m); ++ j)
    53             if (gao2(j, i)) pat[i].PB(j);
    54 }
    55 
    56 int64 DP()
    57 {
    58     CLR (d);
    59     for (int i = 0; i < (1<<m); ++ i)
    60         d[0][i] = gao1(i);
    61 
    62     for (int i = 1; i < n; ++ i)
    63         for (int j = 0; j < (1<<m); ++ j){
    64             d[i][j] = 0;
    65             for (int k = 0; k < (int)pat[j].size(); ++ k)
    66                 d[i][j] += d[i-1][pat[j][k]]; 
    67         }
    68 
    69     return d[n-1][(1<<m)-1];
    70 }
    71 
    72 int main()
    73 {
    74     while (scanf ("%d%d", &n, &m) != EOF && n){
    75         init();
    76         printf ("%lld
    ", DP());
    77     }
    78     return 0;
    79 }
    View Code
    ------------------------------------------------------------------
    现在的你,在干什么呢?
    你是不是还记得,你说你想成为岩哥那样的人。
  • 相关阅读:
    hdu 3342 Legal or Not 拓排序
    hdu 1596 find the safest road Dijkstra
    hdu 1874 畅通工程续 Dijkstra
    poj 2676 sudoku dfs
    poj 2251 BFS
    poj Prime Path BFS
    poj 3278 BFS
    poj 2387 Dijkstra 模板
    poj 3083 DFS 和BFS
    poj 1062 昂贵的聘礼 dijkstra
  • 原文地址:https://www.cnblogs.com/plumrain/p/POJ_2411.html
Copyright © 2011-2022 走看看