Mondriaan's Dream
Time Limit: 3000MS   Memory Limit: 65536K
Total Submissions: 9614   Accepted: 5548

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 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

挺有意思的一道DP,给你一片空地的长和宽,让你用1 * 2的长方形填充空地,使之填满,问有多少种不同的方案。
我是按照Discuss里的一位大神的思路写的,Orz。。。
用2进制的01表示不放还是放
第i行只和i-1行有关
枚举i-1行的每个状态,推出由此状态能达到的i行状态
如果i-1行的出发状态某处未放,必然要在i行放一个竖的方块,所以我对上一行状态按位取反之后的状态就是放置了竖方块的状态。
然后用搜索扫一道在i行放横着的方块的所有可能,并且把这些状态累加上i-1的出发状态的方法数,如果该方法数为0,直接continue。
举个例子
2 4
1111
1111
状态可以由
1100 0000 0110 0011 1111
0000 0000 0000 0000 0000
这五种i-1的状态达到,故2 4 的答案为5

代码如下:PS:这里科普一下运算符的优先级 http://blog.csdn.net/acm_xmzhou/article/details/9804983

#include <cstdio>
#include <cmath>
#include <algorithm>
#include <iostream>
#include <cstring>
#include <map>
#include <string>
#include <stack>
#include <cctype>
#include <vector>
#include <queue>
#include <set> using namespace std;
//#define Online_Judge
#define outstars cout << "***********************" << endl;
#define clr(a,b) memset(a,b,sizeof(a)) #define FOR(i , x , n) for(int i = (x) ; i < (n) ; i++)
#define FORR(i , x , n) for(int i = (x) ; i <= (n) ; i++)
#define REP(i , x , n) for(int i = (x) ; i > (n) ; i--)
#define REPP(i ,x , n) for(int i = (x) ; i >= (n) ; i--)
const int MAXN = 100 + 50;
const int maxw = 100 + 20;
const int MAXNNODE = 1000000 +10;
const long long LLMAX = 0x7fffffffffffffffLL;
const long long LLMIN = 0x8000000000000000LL;
const int INF = 0x7fffffff;
const int IMIN = 0x80000000;
#define eps 1e-8
#define mod 1000000007
typedef long long LL;
const double PI = acos(-1.0);
typedef double D;
typedef pair<int , int> pi;
LL dp[30][1 << 12], i , j , m , n , key = 1;///d[i][j]中i为该状态行数,j为二进制表示的该行状态,1为有木块,0为没有
///d[i][j]的值为该状态下的方法数
void solve(int i , int s , int pos)
{
if(pos == m)///最后一列累加前i行的方法数
{
dp[i][s] += key;
return ;
}
solve(i , s , pos + 1);///不放木块等待下一行竖放
if(pos <= m - 2&&!(s&1 << pos)&&!(s&1 <<(pos + 1)))///可以横放:<= m - 2&&第pos位和第pos + 1位为0(无木块)
solve(i , s|1 << pos|1 << pos + 1 , pos + 2);///把pos和pos+ 1为改为1,然后继续从pos + 2位solve }
int main()
{
//ios::sync_with_stdio(false);
#ifdef Online_Judge
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif // Online_Judge
while(scanf("%d%d",&n, &m),(m||n))
{
clr(dp , 0);
key = 1;
solve(1 , 0 , 0);///先求出第一行的状态
FORR(i , 2 , n)for(int j = 0 ; j < 1 << m ; j++)
{
if(dp[i - 1][j])key = dp[i - 1][j];
else continue;///i - 1行没放木块
solve(i , ~j&((1 << m) - 1) , 0);///只给j位取了反
}
printf("%lld\n",dp[n][(1 << m) - 1]);///终状态的方法数
}
return 0;
}

还有一位大神用的插头DP,看不懂就不解释了。。。
代码如下:
#include<iostream>
#include<cstring>
using namespace std;
long long f[2][1<<12],i,j,ps,p=0,c=1,n,m;
int main()
{
while (scanf("%d%d",&n,&m),n!=0)
{
memset(f[c],0,sizeof(f[c]));
f[c][(1<<m)-1]=1;
for (i=0;i<n;i++)
for (j=0;j<m;j++)
{
swap(p,c);memset(f[c],0,sizeof(f[c]));
for (ps=0;ps<1<<m;ps++)
if (f[p][ps])
{
if (j>0&&(!(ps&(1<<j-1)))&&(ps&(1<<j))) f[c][ps|1<<(j-1)]+=f[p][ps];
if (!(ps&1<<j)) f[c][ps|1<<j]+=f[p][ps];
if (ps&1<<j) f[c][ps^1<<j]+=f[p][ps];
}
}
printf("%lld\n",f[c][(1<<m)-1]);
}
}

POJ 2411的更多相关文章

  1. 状压DP POJ 2411 Mondriaan'sDream

    题目传送门 /* 题意:一个h*w的矩阵(1<=h,w<=11),只能放1*2的模块,问完全覆盖的不同放发有多少种? 状态压缩DP第一道:dp[i][j] 代表第i行的j状态下的种数(状态 ...

  2. poj 2411 Mondriaan&#39;s Dream 【dp】

    题目:id=2411" target="_blank">poj 2411 Mondriaan's Dream 题意:给出一个n*m的矩阵,让你用1*2的矩阵铺满,然 ...

  3. Poj 2411 Mondriaan's Dream(压缩矩阵DP)

    一.Description Squares and rectangles fascinated the famous Dutch painter Piet Mondriaan. One night, ...

  4. Mondriaan's Dream POJ - 2411

    Mondriaan's Dream POJ - 2411 可以用状压dp,但是要打一下表.暴力枚举行.这一行的状态.上一行的状态,判断如果上一行的状态能转移到这一行的状态就转移. 状态定义:ans[i ...

  5. poj 2411 Mondriaan's Dream(状态压缩dP)

    题目:http://poj.org/problem?id=2411 Input The input contains several test cases. Each test case is mad ...

  6. poj 2411 Mondriaan's Dream 轮廓线dp

    题目链接: http://poj.org/problem?id=2411 题目意思: 给一个n*m的矩形区域,将1*2和2*1的小矩形填满方格,问一共有多少种填法. 解题思路: 用轮廓线可以过. 对每 ...

  7. POJ 2411 Mondriaan&#39;s Dream (dp + 减少国家)

    链接:http://poj.org/problem?id=2411 题意:题目描写叙述:用1*2 的矩形通过组合拼成大矩形.求拼成指定的大矩形有几种拼法. 參考博客:http://blog.csdn. ...

  8. POJ 2411 Mondriaan's Dream/[二进制状压DP]

    题目链接[http://poj.org/problem?id=2411] 题意:给出一个h*w的矩形1<=h,w<=11.用1*2和2*1的小矩形去填满这个h*w的矩形,问有多少种方法? ...

  9. POJ 2411 Mondriaan's Dream:网格密铺类 状压dp

    题目链接:http://poj.org/problem?id=2411 题意: 给你一个n*m的网格 (1<=n,m<=11) ,往里面铺1*2或2*1的砖块,问你铺完这个网格有多少种不同 ...

  10. POJ 2411 解题报告

    传送门:http://poj.org/problem?id=2411 题目简述 有一个\(W\)行\(H\)列的广场,需要用\(1*2\)小砖铺满,小砖之间互相不能重叠,问 有多少种不同的铺法? 输入 ...

随机推荐

  1. 使用JDBC进行数据库的事务操作(2)

    本篇将讲诉如何使用JDBC进行数据库有关事务的操作.在上一篇博客中已经介绍了事务的概念,和在MySQL命令行窗口进行开启事务,提交事务以及回滚事务的操作. 似乎事务和批处理都可以一次同时执行多条SQL ...

  2. Servlet的学习之Response响应对象(1)

    在之前学习了Servlet中的主体结构,包括Servlet的生命周期方法,和非生命周期方法能获取的一些非常重要的对象如ServletConfig.ServletContext对象等,而从这篇开始我们将 ...

  3. 发掘ListBox的潜力(三):显示即时提示(Tips)

    ListBox显示即时提示(Tips) Listbox内容太长时超出Listbox宽度的部分将无法显示,一种解决方法是让Listbox产生横向滚动条,滚动显示内容(见前面的<发掘ListBox的 ...

  4. Documentation | AnsibleWorks

    Documentation | AnsibleWorks   Welcome to the Ansible documentation! Ansible is an IT automation too ...

  5. Windows Azure中的Affinity Group

    Affinity Group: (近亲组?个人认为直译为近亲组更好一些,不知道官方是怎么翻译的). 如何创建Affinity Group 1. 进入https://manage.windowsazur ...

  6. CImageList使用简要说明

    CImageList ImageList;//创建一个包含3个24位色32x32图片的ImageList,ILC_MASK的意思是同时创建一个mask,这样在下面指定了背景颜色以后ImageList就 ...

  7. Lucene.Net 2.3.1开发介绍 —— 二、分词(四)

    原文:Lucene.Net 2.3.1开发介绍 -- 二.分词(四) 2.1.2 可以使用的内置分词 简单的分词方式并不能满足需求.前文说过Lucene.Net内置分词中StandardAnalyze ...

  8. form表单多值提交

    $.ajax({ cache: true, type: "POST", url:ajaxCallUrl, data:$('#yourformid').serialize(),// ...

  9. Git 使用规范流程(转)

    团队开发中,遵循一个合理.清晰的Git使用流程,是非常重要的. 否则,每个人都提交一堆杂乱无章的commit,项目很快就会变得难以协调和维护. 下面是ThoughtBot 的Git使用规范流程.我从中 ...

  10. HDU 1254 推箱子游戏(搞了一下午。。。)

    中文题目:http://acm.hdu.edu.cn/showproblem.php?pid=1254 一开始常规的人用来做主导,想着想着不对劲,其实是箱子为主导,人只是箱子能否推进的一个判断. 可以 ...