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. C#中Base64之编码,解码方法

    原文:C#中Base64之编码,解码方法 1.base64  to  string string strPath =  "aHR0cDovLzIwMy44MS4yOS40Njo1NTU3L1 ...

  2. boost.asio系列——socket编程

    asio的主要用途还是用于socket编程,本文就以一个tcp的daytimer服务为例简单的演示一下如何实现同步和异步的tcp socket编程. 客户端 客户端的代码如下: #include &l ...

  3. DataGridView ——管理员对用户的那点操作

    记得第一次做机房收费系统的时候,就在加入删除用户这出现了点小问题,由于一直都是一个容不得一点瑕疵的人.所以对查询用户的时候查询一次就会多一些空行我非常是不能容忍.看似非常小的问题,我却花了非常长的时间 ...

  4. C++ 可以多个函数声明

    c/c++可以有多个函数声明,但实现只能有一个 例子: //file t_defs.h #ifndef _T_DEFS_H_ #define _T_DEFS_H_ void say(void); #e ...

  5. Mysql 官方Memcached 插件初步试用感受 - schweigen - ITeye技术网站

    Mysql 官方Memcached 插件初步试用感受 - schweigen - ITeye技术网站 Mysql 官方Memcached 插件初步试用感受

  6. 系统没有“internet信息服务(IIS)管理器”

    系统没有“internet信息服务(IIS)管理器” | 浏览:8981 | 更新:2014-06-19 14:43 1 2 3 4 5 6 7 分步阅读 很多用户都在咨询:系统控制面板的管理工具中没 ...

  7. Hibernate(六)——多对多关联映射

    前面几篇文章已经较讲解了三大种关联映射,多对多映射就非常简单了,不过出于对关联映射完整性的考虑,本文还是会简要介绍下多对多关联映射. 1.单向多对多关联映射 情景:一个用户可以有多个角色,比如数据录入 ...

  8. Ello讲述Haar人脸检测:易懂、很详细、值得围观

    源地址:http://www.thinkface.cn/thread-142-1-1.html 由于工作需要,我开始研究人脸检测部分的算法,这期间断断续续地学习Haar分类器的训练以及检测过程,在这里 ...

  9. [SVN]创建本地的SVN仓库

    本地创建SVN仓库,就算是自己平时写代码也养成使用SVN的习惯. 环境: OS:Mac OS X10.9.1 SVN Version:1.7.10 创建本地SVN仓库: $svnadmin creat ...

  10. GNU C的使用

    基本语法 gcc [options] [filenames]  说明:  在gcc后面可以有多个编译选项,同时进行多个编译操作.很多 的gcc选项包括一个以上的字符.因此你必须为每个选项指定各 自 ...