Mondriaan's Dream (like pressure dp)

Mondriaan's Dream (like pressure dp)

Time Limit: 3000MS
Memory Limit: 65536K
judge:poj 2411
source:Ulm Local 2000

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.

judge:poj 2411

Input

judge:poj 2411

Output

judge:poj 2411

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

The meaning of problems

Give you one n m n * m block, with 1 2 1 * 2 bricks covered with it, ask you a total of how many shop law.

Like pressure dp exercises, as are full amount on the OK through from the first position to start the enumeration (the results already obtained by the recursive) that each row corresponding to the position of all possible states, and finally to see the state.

time complexity O ( n m 2 m ) O(n*m*2^m)

Code

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <string>
#include <cstring>
#include <vector>
#include <queue>
#include <map>
#define m_p make_pair
#define maxn 12
#define maxm 505
#define _for(i, a) for(LL i = 0; i < (a); i++)
#define _rep(i, a, b) for(LL i = (a); i <= (b); i++)
#define outval(a) cout<<#a<<": "<<a<<"\n"
using namespace std;
typedef long long LL;
const LL MAXN = 110;
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3f;

const double eps = 1e-10;

LL dp[2][1 << maxn];
int n, m;
LL *Crt = dp[0], *Next = dp[1];

void init() {

}

LL solve() {
	Crt[0] = 1;
	for (int i = n - 1; i >= 0; i--) {
		for (int j = m - 1; j >= 0; j--) {
			_for(used, (1 << m)) {//0:need put   1:don't put
				if (used & (1 << j)) {
					//don't put
					Next[used] = Crt[used & ~(1 << j)];
				}
				else {
					//need put
					LL res = 0;
					//the first way
					if (j + 1 < m && !(used & (1 << (j + 1)))) {
						res += Crt[used | (1 << (j + 1))];
					}
					//the second way
					if (i + 1 < n) {
						res += Crt[used | (1 << j)];
					}
					Next[used] = res;
				}
			}
			swap(Crt, Next);
		}
	}
	return Crt[0];
}


int main() {
	ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
	//freopen("in.txt", "r", stdin);

	while (cin >> n >> m, n) {
		cout << solve() << "\n";
	}
	return 0;
}

/*

*/

Published 163 original articles · won praise 54 · views 30000 +

Guess you like

Origin blog.csdn.net/weixin_42856843/article/details/102102059