• 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
    ------------------------------------------------------------------
    现在的你,在干什么呢?
    你是不是还记得,你说你想成为岩哥那样的人。
  • 相关阅读:
    volatile 关键字,你真的理解吗?
    kafka如何彻底删除topic及数据
    CentOS7 安装letsencrypt
    Qunar风控安全产品的探索之路
    乐观锁的实际应用
    前端打包报错内存溢出
    Exception in thread "main" java.lang.UnsatisfiedLinkError: Can't load library: /usr/lib/jvm/java11openjdkamd64/lib/libawt_xawt.so
    GitHud加速工具 devsidecar 安装
    linux系统命令行或shell里面设置终端title标题(适用与ubuntu,centos)[转]
    Sublime 搜索显示<binary>
  • 原文地址:https://www.cnblogs.com/plumrain/p/POJ_2411.html
Copyright © 2020-2023  润新知