hdu 三部曲 Mondriaan's Dream

Problem 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
*********************************************************************************************
二进制状态压缩,终于把这个题弄弄明白了!!解释简代码
*********************************************************************************************
 1 /*
 2 状态压缩,用二进制,
 3 0表示竖放的前行,则下一行必定为1,
 4 1表示横放,对下一行没有干扰
 5 */
 6 #include<iostream>
 7 #include<string>
 8 #include<cstring>
 9 #include<cmath>
10 #include<cstdio>
11 #include<algorithm>
12 using namespace std;
13 long w,h,i;
14 long long  dp[15][(1<<13)];
15 bool qihe(long x)//判断合法状态
16   {
17       for(long i=0;i<w;)
18        if((x&(1<<i))>0)
19          {
20            if((i==w-1)||((x&(1<<(i+1)))==0))
21             return false;
22            i+=2;
23          }
24         else  i++;
25       return true;
26   }
27   bool tran(int a,int b)//判断上一行的a状态转化到下一行的b状态是否切合
28 {
29     for(int i=0;i<w;)
30     {
31         if((a&(1<<i))>0)
32         {
33             if((b&(1<<i))==0)i++;
34             else if(i==w-1||(a&(1<<(i+1)))==0||(b&(1<<(i+1)))==0)return 0;
35             else i+=2;
36         }
37         else if((b&(1<<i))>0)i++;
38         else return 0;
39     }
40     return 1;
41 }
42   int main()
43   {
44       while(cin>>h>>w)
45      {
46          if(h==0&&w==0)
47           break;
48       memset(dp,0,sizeof(dp));
49       if(w==0||h==0)
50       {
51           printf("0\n");
52           continue;
53       }
54       if(w>h)
55       {
56           int tmp;
57           tmp=w;
58           w=h;
59           h=tmp;
60       }
61       int z=1<<w;
62       for(i=0;i<z;i++)//第一行拿出来单独处理
63        if(qihe(i))
64         dp[1][i]=1;
65       for(i=2;i<=h;i++)
66        {
67            for(long j=0;j<z;j++)
68             {
69                 dp[i][j]=0;
70                 for(long k=0;k<z;k++)
71                  if(tran(k,j))//状态转化
72                    dp[i][j]+=dp[i-1][k];
73             }
74        }
75       cout<<dp[h][z-1]<<endl;//输出结果
76      }
77       return 0;
78 
79   }
View Code

坚持!!!!胜利!!!!

转载于:https://www.cnblogs.com/sdau--codeants/p/3311713.html

猜你喜欢

转载自blog.csdn.net/weixin_34417635/article/details/93727623