• poj 2411 Mondriaan's Dream(状态压缩dP)


    题目:http://poj.org/problem?id=2411

    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.

    题意:一个矩阵,只能放1*2的木块,问将这个矩阵完全覆盖的不同放法有多少种。

    思路:一道很经典的状态dp,但是还是很难想,横着放定义为11,竖着放定义为01.

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <cstdlib>
     5 using namespace std;
     6 __int64 d[12][1<<12], f[1<<12];//用———int64,因为有可能数很大
     7 int h, w, full;
     8 
     9 bool ok(int x) //判断一行里是否出现连续奇数个1,第一行的话不允许
    10 {
    11     int sum = 0;
    12     while(x>0)
    13     {
    14         if((x&1)==1)
    15         sum++;
    16         else
    17         {
    18             if((sum&1)==1)
    19             return false;
    20             sum = 0;
    21         }
    22         x = (x>>1);
    23     }
    24     if((sum&1)==1)
    25             return false;
    26     return true;
    27 }
    28 bool check(int x1, int x2)
    29 {
    30     int xx = (1<<w)-1;
    31     if((x1|x2)==xx&&f[x1&x2])//去掉竖着00和竖着单独11的情况,一定不要忘了单独11的情况
    32     return true;
    33     return false;
    34 }
    35 int main()
    36 {
    37     int i, j, k;
    38     memset(f, 0, sizeof(f));
    39     full = (1<<11);
    40 
    41     for(i = 0; i < full; i++)
    42     if(ok(i))
    43     f[i] = 1;   //记录连续的奇数个1
    44     while(~scanf("%d%d", &h, &w))
    45     {
    46         if(h==0&&w==0)
    47         break;
    48         full = (1<<w);
    49         memset(d, 0, sizeof(d));
    50         for(i = 0; i < full; i++)
    51         if(f[i])
    52         d[0][i] = 1;
    53 
    54         for(k = 1; k < h; k++)
    55         for(i = 0; i < full; i++)
    56         for(j = 0; j < full; j++)
    57         {
    58             if(check(i, j))
    59             d[k][i] += d[k-1][j];
    60         }
    61         printf("%I64d
    ", d[h-1][full-1]); //最后一行,而且满1
    62     }
    63     return 0;
    64 }
  • 相关阅读:
    第三天 moyax
    mkfs.ext3 option
    write file to stroage trigger kernel warning
    download fomat install rootfs script
    custom usb-seriel udev relus for compatible usb-seriel devices using kermit
    Wifi Troughput Test using iperf
    learning uboot switch to standby system using button
    learning uboot support web http function in qca4531 cpu
    learngin uboot design parameter recovery mechanism
    learning uboot auto switch to stanbdy system in qca4531 cpu
  • 原文地址:https://www.cnblogs.com/bfshm/p/3585598.html
Copyright © 2020-2023  润新知