POJ 2411 & HDU 1400 Mondriaan's Dream, poj2411
Mondriaan's Dream
Time Limit:3000 MS |
|
Memory Limit:65536 K |
Total Submissions:12341 |
|
Accepted:7204 |
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 into rical tilings multiple times.
Sample Input
1 21 31 42 22 32 42 114 110 0
Sample Output
10123514451205
Source
Ulm Local 2000
Question link: http://poj.org/problem? Id = 2411
How many methods are there to combine a small rectangle of 1*2 into a large rectangle of h * w?
Question Analysis: First, if the area of the large rectangle is odd, it cannot be combined. Otherwise, because h and w are not very large, we adopt the State compression idea and use 1 to indicate the vertical state, 0 indicates the state of the horizontal line. For example, the state of the first and second line in is:
0 0 1 0 0 0 1 1 0 0
1 1 1 1 0 0 1 1 0 0, dp [I] [j] indicates the number of methods when the status of 1st rows is j, apparently for the vertical status, the row where the vertical part is located has an impact on the lower part, while the horizontal state only has an impact on the current row. We should first consider the horizontal, because the area of the small rectangle is 2, the number of grids in the two adjacent vertical bars must be an even number, for example, 1 0 0 0 1, in this case, the grid with zero values obviously cannot form a complete horizontal state, and the grid with one value 0 and one value 0 and one value 0 and one value 0 and one value 0 and one value 0 and one value 0 and one value 0 and one value 0 and 1 respectively, it will have an impact on the next row, and the column corresponding to the current row must be 1 for the previous behavior 1, in this way, we can set the current Behavior 1 to 0 (because its status has been uniquely determined by 1 in the previous row) this is used to set the value of the previous row & current row to 0, which is regarded as the legal state under the vertical condition, because if the previous behavior is 0, the current row can be 0 or 1, the current row of the previous behavior 1 must be 0 and the result is 0.
1 0 0 1 1 0 0 1
1 0 0 0, which is regarded as an invalid vertical state, 0 0 0 0. When the vertical legal state, the horizontal legal state has been described above, we can use a function to judge.
Initialize dp [0] [0] as 1, and push from the first line to the row h. The answer is dp [h] [0]. this indicates the number of methods in row h with a status of 0. The state 0 here is equivalent to not giving it the status, because the status of the last row has been uniquely determined by the previous row. In other words, the status of the last row without a grid is uncertain, either as the lower half of the vertical line or as a valid state of horizontal
# Include <cstdio> # include <cstring> # define ll long longll dp [12] [(1 <12)]; int h, w; bool OK (int t) {int cnt = 0; for (int I = 0; I <w; I ++) {if (t & 1) {if (cnt & 1) // determine the number of zeros between two adjacent ones return false;} else cnt ++; t >>=1;} if (cnt & 1) // determine the number of 0 on the left of the last 1. return false; return true;} int main () {while (scanf ("% d", & h, & w )! = EOF & (w + h) {if (h * w) & 1) // an odd number of areas cannot be combined, because an even unit area is {printf ("0 \ n"); continue;} memset (dp, 0, sizeof (dp )); dp [0] [0] = 1; for (int I = 1; I <= h; I ++) for (int j = 0; j <(1 <w); j ++) for (int k = 0; k <(1 <w); k ++) if (k & j) = 0) & OK (k ^ j) dp [I] [j] + = dp [I-1] [k]; printf ("% lld \ n", dp [h] [0]);}