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
1 <= H, W <= 11. Data is limited. You can use the state compression method.
First, we need to calculate the number of ways to splice a rectangle of 1*2 into a rectangle of N * m.
In two steps, 1) first find the Conversion Relationship between the adjacent two rows
2) The transformation relationship between two adjacent rows is used to calculate the matrix that can be assembled into N * m after N conversions.
Do some explanations on the basis of others:
1) The status flag occupies 1 for both horizontal and vertical positions, and 1 for vertical positions (0 for upper and lower 1). If the two positions are not placed, 0 is displayed. Each row can be converted to a binary number.
When this row is completed, the team should be 11111 (M), that is, 2 m-1, DP [N] [2 ^ s-1], that is, the final result.
The vertical column only occupies one place, because we are recursive from the lower left to the upper right corner. It can be vertical here, indicating that the first line of it is not placed here, that is, 0.
The calculation of this row can only be obtained by recursion of the first row. Therefore, you can use a scrolling array to save a little memory (not important ).
// Based on horizontal and vertical la S, you can combine each row into a binary number based on 01, which is actually state compression.
There are three ways to place each location:
1. Vertical placement
2. Horizontal placement
3. Do not place
D indicates the current column number. initialize D, S1, and S2 to 0. corresponding to the above three placement methods, S1 and S2 are adjusted to S1 as the current row and S2 as the previous row of the current row.
1. d = d + 1, S1 <1 | 1, S2 <1; // place the current Behavior 1 vertically and the previous behavior 0
2. d = d + 2, S1 <2 | 3, S2 <2 | 3; // All are 11 (11 = 3)
3. D = d + 1, S1 <1, S2 <1 | 1; // The status of the last Behavior 1, which cannot be vertical or unplaced, horizontal playback can be expanded to the right without calculation)
// S1 <1 | 1 indicates that S1 is first shifted to 1 bit, and then bitwise OR the binary number of 1, that is, 01.
In addition, the first line is calculated separately.
// ================================================ ==================================================================== // Name: poj2411.cpp // Author: // version: // copyright: Your copyright notice // Description: Hello world in C ++, ANSI-style // ========================================== ========================================================== = # include <iostream> # include <stdio. h> # include <string. h> using namespace STD; int const maxn = (1 <11) ;__ int64 DP [11] [4100]; int m, n, row; void DFS (int c, int S, int PS) {If (C> m) return; If (C = m) {DP [row] [s] + = DP [row-1] [PS]; return;} DFS (C + 1, S <1, (Ps <1) | 1); // do not put DFS (C + 1, (S <1) | 1, ps <1); // vertically put DFS (C + 2, (S <2) | 3, ps <2 | 3); // horizontal} void dfs_first (int c, int s) {If (C> m) return; if (C = m) {DP [0] [s] = 1;} dfs_first (C + 1, S <1 ); // do not place dfs_first (C + 2, (S <2) | 3); // horizontal} int main () {freopen ("in.txt", "r ", stdin); int I; while (scanf ("% d", & M, & N), m) {If (M * n % 2) {puts ("0"); continue;} If (M <n) Swap (m, n); memset (DP, 0, sizeof (DP )); dfs_first (0, 0); for (I = 1; I <n; I ++) {ROW = I; DFS (0, 0, 0 );} printf ("% i64d \ n", DP [n-1] [(1 <m)-1]);} return 0 ;}