【POJ 2411】【Mondriaan's Dream】

题目:

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

题意:就是任意给我们长宽不超过11的两个数字,让长为2宽为1的小长方形拼,问能有多少种拼接方式。

扫描二维码关注公众号,回复: 2832292 查看本文章

解题思路:刚上来一点dp的想法没有,居然在想能不能暴力或者找规律解出来,后来想想年轻了,dp,以每行之间的递推关系实现,当前行的状态取决去上行的,并且又决定下行的状态,然后,小矩形的放置有三种方式,横着,竖着,不放,这三者分别对应了三个不同的操作,影响也是不同的,因为种类确实很多,然后决定用dfs来跑一次这些放置方式,上述的三种放置方式就对应于三种不同的dfs。

ac代码:

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#define maxn 14005
using namespace std;
typedef long long ll;
int mp[maxn][2];
ll dp[15][maxn];
int w,h,tan;

void  dfs(int l,int now,int pre)
{
	if(l>w) return ;//列跑完之后,直接跳出 
	if(l==w)
	{
		mp[tan][0]=pre;
		mp[tan++][1]=now;
		return ;
	}
	dfs(l+2,(now<<2)|3,(pre<<2)|3);
	dfs(l+1,(now<<1)|1,pre<<1);
	dfs(l+1,now<<1,(pre<<1)|1);
	//规定竖放的长方形,上边为1,下边为0 
}

int main()
{
	while(scanf("%d%d",&h,&w)!=EOF)
	{
		if(h==0&&w==0) break;
		if(h<w) swap(h,w);//因为涉及到列的dfs,将小的作为列,因为会涉及列的dfs 
		tan=0;
		dfs(0,0,0);//开始遍历dfs 得到第一行的数据 
		memset(dp,0,sizeof(dp));
		dp[0][(1<<w)-1]=1;
		for(int i=0;i<h;i++)
			for(int j=0;j<tan;j++)
				dp[i+1][mp[j][1]]+=dp[i][mp[j][0]];
		printf("%lld\n",dp[h][(1<<w)-1]);	
	} 
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_42505741/article/details/81744490