Mondriaan's Dream (zoj 1100 状压dp)

原创 2015年11月21日 19:31:55
Mondriaan's Dream

Time Limit: 10 Seconds      Memory Limit: 32768 KB

Squares and rectangles fascinated the famous Dutch painter Piet Mondriaan.One night, after producing the drawings in his 'toilet series' (where hehad to use his toilet paper to draw on, for all of his paper was filledwith squares and rectangles), he dreamt of filling a large rectangle withsmall 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 acomputer to calculate the number of ways to fill the large rectanglewhose dimensions were integer values, as well. Help him, so that hisdream won't turn into a nightmare!

Input Specification

The input file contains several test cases. Each test case is made up oftwo integer numbers: the height h and the width w of thelarge rectangle. Input is terminated by h=w=0. Otherwise,1<=h,w<=11.

Output Specification

For each test case, output the number of different ways the given rectanglecan be filled with small rectangles of size 2 times 1. Assume the givenlarge 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



Source: University of Ulm Local Contest 2000



/*************************************************************************
    > File Name: zoj1100_铺砖_状压.cpp
    > Author: wust_lyf
    > Mail: 2206478849@qq.com
    > Created Time: 2015年11月21日 星期六 16时39分14秒
 ************************************************************************/

/*
  题意:一个n*m的方格,要求用1*2的砖把它铺满,问有多少种铺法。
  思路:dp[i][j]表示第i行在状态j下所有合法的铺法总数。第i行的状态可以由第i-1行推得,且易知
  第i-1行的空缺只能由第i行对应位置用竖着的砖来补上。
 */

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<queue>
#include<map>
#include<set>
#include<stack>
#define eps 1e-6
#define DBG printf("Hi\n")
using namespace std;
typedef long long ll;
const int INF = 0x3f3f3f3f;
const int maxn = 1005;
const int MAXN = 2005;

ll dp[12][(1<<11)+10];
int n,m;

bool isok(int s)		//判断s状态能否只用横着的砖铺满
{
	for (int i=0;i<m;)
	{
		if (s&(1<<i))
		{
			if (i==m-1) return false;
			if ((s&(1<<(i+1)))==0) return false;  //第i个可以铺但第i+1个不能铺则说明这个状态不能满足
			i+=2;
		}
		else i++;
	}
	return true;
}

ll dfs(int dep,int pre)
{
	if (dep==(n+1)) return (pre==(1<<m)-1)?1:0;
	if (dp[dep][pre]!=-1) return dp[dep][pre];
	int need=((1<<m)-1)&(~pre);			//need记录为了补上一行的空缺该行要竖着放的位置
	dp[dep][pre]=0;
	for (int cur=0;cur<(1<<m);cur++)  //cur是指当前这一层要铺砖的状态
	{
		if ((cur&need)!=need) continue;		//首先判断这个状态是否包含需要竖着放的位置
		if (isok(cur^need))        //判断去掉竖着放的位置其他需要横着放的位置是否可行
			dp[dep][pre]+=dfs(dep+1,cur);
	}
	return dp[dep][pre];
}

int main()
{
	int i,j;
	while (scanf("%d%d",&n,&m))
	{
		if (n==0&&m==0) break;
		if ((n*m)%2){
			printf("0\n");
			continue;
		}
		if (n<m) swap(n,m);
		memset(dp,-1,sizeof(dp));
		printf("%lld\n",dfs(1,(1<<m)-1));
	}
    return 0;
}



ZOJ1100 状压DP +深搜

记得做过类似于这类题目是可以用组合数学方法来解决的,可惜淡忘了,也找不到了,看了网上的也有人提到过可以用组合公式解决,可是没人做,都是用了状压DP的方法,这个状压很难讲清楚吧,推荐两篇 第一...
  • u010682557
  • u010682557
  • 2014年06月21日 15:31
  • 744

zoj 1100 铺砖 状态压缩

1、st中存的是每一行摆放的所有可能,0是空着,1是占着,st[i][0]中存一行的可能的状态即from,st[i][1]中存与其匹配的下一行状态即to; 2、dfs中from是一行中前n个格子的状...
  • yan_____
  • yan_____
  • 2013年03月26日 00:23
  • 1673

POJ2411——Mondriaan's Dream(轮廓线dp入门)

Mondriaan's Dream Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 1520...
  • say_c_box
  • say_c_box
  • 2016年08月03日 20:12
  • 434

【POJ2411】Mondriaan's Dream-状态压缩DP(插头DP?)

【POJ2411】Mondriaan's Dream-状态压缩DP(插头DP?)
  • Maxwei_wzj
  • Maxwei_wzj
  • 2017年03月20日 17:46
  • 259

poj2411 Mondriaan's Dream 插头dp做法

Mondriaan's Dream Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 11379...
  • smz436487
  • smz436487
  • 2014年07月25日 13:56
  • 251

poj 2411 Mondriaan's Dream 【dp】

题目:poj 2411 Mondriaan's Dream 题意:给出一个n*m的矩阵,让你用1*2的矩阵铺满,然后问你最多由多少种不同的方案。 分析:这是一个比较经典的题目,网上...
  • y990041769
  • y990041769
  • 2014年10月09日 07:46
  • 1337

POJ2411:Mondriaan's Dream(状态压缩)

Description Squares and rectangles fascinated the famous Dutch painter Piet Mondriaan. One night, a...
  • libin56842
  • libin56842
  • 2014年05月04日 22:44
  • 2685

zoj 1100 - Mondriaan's Dream

题目:在m*n的地板上铺上相同的1*2的地板砖,问有多少种铺法。 分析:dp,组合,计数。经典dp问题,状态压缩。             状态:设f(i,j)为前i-1行铺满,第i行铺的状态的位表示...
  • mobius_strip
  • mobius_strip
  • 2014年10月10日 12:34
  • 1257

ZOJ 1100 Mondriaan's Dream

中等难度的DP。铺砖问题,有组合数学公式。 但是用搜索+dp的方法更……好吧,也很难做。研究了一个下午的标程,终于搞懂。把每一层的砖块压缩为二进制编码,搜索上一层到当前层的状态转化是否能够达到。然后从...
  • Crux_D
  • Crux_D
  • 2008年03月22日 16:44
  • 4230

ZOJ 1100 Mondriaan's Dream

一道一开始不知道是用DP的题目  也许是对DP的理解不深 看了题解之后发现很容易... 思路      两个变量, 输入的左边是W 右边是 S 要找一条最长的序列使得W是递增而S是递减的 明白题...
  • DIOML
  • DIOML
  • 2016年03月17日 19:10
  • 186
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Mondriaan's Dream (zoj 1100 状压dp)
举报原因:
原因补充:

(最多只允许输入30个字)