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
    ------------------------------------------------------------------
    现在的你,在干什么呢?
    你是不是还记得,你说你想成为岩哥那样的人。
  • 相关阅读:
    关于C++中如何判断文件,目录存在的若干方法
    AStyle2.02在VS2008下的使用
    opencv与wxwidgets冲突(第三方库jpeg,tiff,png,zlib所引起)
    C和C++获取文件大小的方法总结
    跨平台项目组织2
    md5函数C语言实现
    分享本人自编的一个跨平台项目:伙食管理小软件
    win7 vs2008 release mt.exe停止工作
    跨平台项目组织
    SQL注入语句 (很全)
  • 原文地址:https://www.cnblogs.com/plumrain/p/POJ_2411.html
Copyright © 2011-2022 走看看