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

    Mondriaan's Dream
    Time Limit: 3000MS   Memory Limit: 65536K
    Total Submissions: 17769   Accepted: 10198

    Description

    Squares and rectangles fascinated the famous Dutch painter Piet Mondriaan. One night, after producing the drawings in his 'toilet series' (where he had to use his toilet paper to draw on, for all of his paper was filled with squares and rectangles), he dreamt of filling a large rectangle with small rectangles of width 2 and height 1 in varying ways.

    Expert as he was in this material, he saw at a glance that he'll need a computer to calculate the number of ways to fill the large rectangle whose dimensions were integer values, as well. Help him, so that his dream won't turn into a nightmare!

    Input

    The input contains several test cases. Each test case is made up of two integer numbers: the height h and the width w of the large rectangle. Input is terminated by h=w=0. Otherwise, 1<=h,w<=11.

    Output

    For each test case, output the number of different ways the given rectangle can be filled with small rectangles of size 2 times 1. Assume the given large rectangle is oriented, i.e. count symmetrical tilings multiple times.

    Sample Input

    1 2
    1 3
    1 4
    2 2
    2 3
    2 4
    2 11
    4 11
    0 0
    

    Sample Output

    1
    0
    1
    2
    3
    5
    144
    51205
    

    Source

     
    【题解】
    状压DP常规思路:预处理所有合法状态
    由于对当前行防止方案有影响的为当前行的上一行,所以我们要确定当前行状态为s1时,
    上一行的合法状态s2
    dfs预处理,now表示当前行,pre表示上一行
    0表示 不放
    1表示 横放 或者 竖放的下一格
    对于位置d,有三种决策:
    1、横放,pre相同的位置必须为1,否则无法被填充,不合法
    2、竖放,pre相同位置必须为0,否则放不下
    3、不放,pre相同位置必须为1,要不你那什么填充那个位置?
    然后转移即可。dp[i][j]表示第i行为状态j的方案数。
    初始:虚拟一行0,全为1,表示第一行只能横放或者不放
    采用刷表法,状压DP刷表法很好用
     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstdlib>
     4 #include <cstring>
     5 #include <cmath> 
     6 #include <algorithm>
     7 #define min(a, b) ((a) < (b) ? (a) : (b))
     8 #define max(a, b) ((a) > (b) ? (a) : (b))
     9  
    10 inline void read(long long &x)
    11 {
    12     x = 0;char ch = getchar(), c = ch;
    13     while(ch < '0' || ch > '9')c = ch, ch = getchar();
    14     while(ch <= '9' && ch >= '0')x = x * 10 + ch - '0', ch = getchar();
    15     if(c == '-')x = -x;
    16 }
    17 
    18 const long long INF = 0x3f3f3f3f; 
    19 const long long MAXW = 15;
    20 const long long MAXH = 15;
    21 
    22 long long status[1 << MAXH][2], w, h, tot, dp[MAXW][1 << MAXH];//[0]代表pre,[1]代表now
    23 
    24 /*
    25 状态定义:
    26 0:不放 或者 竖着的上面一格
    27 1:横着的 或者 竖着的下面一格 
    28 */
    29 
    30 void dfs(long long pre, long long now, long long d)
    31 {
    32     if(d > h)return;
    33     if(d == h)
    34     {
    35         status[++tot][0] = pre;
    36         status[tot][1] = now;
    37         return;
    38     }
    39     dfs((pre << 2) | 3, (now << 2) | 3, d + 2);
    40     dfs(pre << 1, (now << 1) | 1, d + 1);
    41     dfs((pre << 1) | 1, now << 1, d + 1);
    42 } 
    43 
    44 int main()
    45 {
    46     read(w), read(h);
    47     while(w + h)
    48     {
    49         tot = 0;
    50         dfs(0,0,0);
    51         memset(dp, 0, sizeof(dp));
    52         dp[0][(1 << h) - 1] = 1;
    53         for(register long long i = 0;i < w;++ i)
    54         {
    55             for(register long long j = 1;j <= tot;++ j)
    56                 dp[i + 1][status[j][1]] += dp[i][status[j][0]];
    57         }
    58         printf("%lld
    ", dp[w][(1 << h) - 1]); 
    59         read(w), read(h);
    60     }
    61     return 0;
    62 }
    POJ2411
  • 相关阅读:
    中国年薪 ¥30 万和美国年薪$ 10 万的生活水平异同
    汽车之家CMDB设计思路 – 汽车之家运维团队博客
    平民软件 | 中间件
    FIT2CLOUD
    ZeroBrane Studio
    新炬网络-领先数据资产运营商 | 数据资产管理 | 数据库运维 | 自动化运维
    中国(南京)软件开发者大会
    夏仲璞 | 全球软件开发大会北京站2016
    Nginx下流量拦截算法 | 夏日小草
    docker~dockertoolbox的加速器
  • 原文地址:https://www.cnblogs.com/huibixiaoxing/p/7505068.html
Copyright © 2011-2022 走看看