Mondriaan's Dream (zoj 1100 状压dp)
2015-11-21 19:31
405 查看
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.
![](http://acm.zju.edu.cn/onlinejudge/showImage.do?name=0000%2F1100%2F1100-1.gif)
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.
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;
}
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.
![](http://acm.zju.edu.cn/onlinejudge/showImage.do?name=0000%2F1100%2F1100-1.gif)
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 Input1 2 1 3 1 4 2 2 2 3 2 4 2 11 4 11 0 0 | Sample Output1 0 1 2 3 5 144 51205 | ![]() |
/*************************************************************************
> 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;
}
相关文章推荐
- POJ 3254 - Corn Fields [状压DP]
- poj 2836
- poj 3254
- POJ 2441
- 2014 西安邀请赛状压DP
- Mega Man’s Missions
- HDU 5135 Little Zu Chongzhi's Triangles (2014年广州赛区现场赛I题)
- Codevs2880 送外卖
- codeforces #302 Remembering Strings (dp)
- hdu 5418 Victor and World 状压DP
- Codeforces Round #235 (Div. 2) D. Roman and Numbers(状压dp)
- Codeforces Round #302 (Div. 2) E. Remembering Strings(状压dp)
- poj(3254)——Corn Fields
- SDUT 3061 聪明的玛雅 (状压DP)
- POJ 3254 Corn Fields (状压DP+滚动数组)
- POJ 1185 炮兵阵地 (状压DP)
- POJ 3311 Hie with the Pie (状压DP)
- HDU 2167 Pebbles (状压DP)
- (福大2015年3月月赛)FZU 2186 小明的迷宫 (BFS+状压DP)
- HDU 4628 Pieces (状压DP)