Mondriaan's Dream

Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)

Total Submission(s): 783    Accepted Submission(s): 506

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

解题思路:

如图:问铺满大举行一共同拥有多少种方法。

由于长宽最大11,能够状态压缩.

从第一行開始铺砖。

dp[ i ]  [ j ] 定义为 第i行的状态为 j 一共同拥有多少种方法 .

把小矩形用01状态表示,小矩形由两个正方形组成。 对于横着放的小矩形,左右两个正方形用11表示,对于竖着的小矩形,上下两个正方形用分别01表示。

第i行的状态s2与第i-1行的状态s1有关。

s1和s2满足两个条件:

1.   s1  |  s2  得到的数二进制每一位都是1 ,由于对于竖着放的 ,0|1肯定是1,横着放的都是11,相或也是11.

2.   s1  & s2  得到的数连续的1是偶数个,注意0也是偶数。这个看图观察就能够了。

本题犯的错误:

1.

获取一个数x二进制的第i位是0或者1。用 if( x&(1<<i) ==1) 是不正确的, 这句话的意思是,把x的二进制数除了第i位都设为0,第i位通过 &1,来推断是0或者1,可是得到的数不一定是1,是2的倍数,比方 0010  或者 0100.

2.

推断一个数x二进制的每一位是否等于1 ,如果有m位 , 直接用 if( x==1<<m)-1),不用每一位的推断。前者效率更高。

代码:

#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include <vector>
#include <algorithm>
#include <string.h>
using namespace std;
#define ll long long
ll dp[12][1<<12];//dp[i][j]表示第i行状态为j有多少种方法
int n,m; bool ok(int s1,int s2)
{
int temp=s1|s2;//两个状态或运算每一位都必须是1
if(temp!=(1<<m)-1)
return false;
int cnt=0;
temp=s1&s2;//两个状态且运算,必须连续的1都是偶数个
for(int i=0;i<m;i++)
{
if((temp&(1<<i)))//第i位是1
cnt++;
else
{
if(cnt&1)
return false;
}
}
if(cnt&1)
return false;
return true;
} void solve()
{
memset(dp,0,sizeof(dp));
int maxd=1<<m;
for(int i=0;i<maxd;i++)//铺第一行
if(ok(maxd-1,i))
dp[1][i]++;
for(int i=2;i<=n;i++)//铺第i行
{
for(int j=0;j<maxd;j++)
{
for(int k=0;k<maxd;k++)
if(ok(j,k))
dp[i][j]+=dp[i-1][k];
}
}
ll ans=0;
ans+=dp[n][maxd-1];//最后一行肯定都是1
printf("%I64d\n",ans);
} int main()
{
while(scanf("%d%d",&n,&m)!=EOF)
{
if(!n||!m)
break;
if(n*m&1)//小方块的个数为奇数个,肯定不能铺满
{
printf("0\n");
continue;
}
if(n<m)
n=n^m,m=n^m,n=n^m;
solve();
}
return 0;
}

[ACM] HDU 1400 Mondriaan&#39;s Dream (状态压缩,长2宽1长方形铺满)的更多相关文章

  1. [ACM] HDU 5025 Saving Tang Monk (状态压缩,BFS)

    Saving Tang Monk Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) ...

  2. hdu 4057 AC自己主动机+状态压缩dp

    http://acm.hdu.edu.cn/showproblem.php?pid=4057 Problem Description Dr. X is a biologist, who likes r ...

  3. hdu 1400 Mondriaan's Dream 解题报告

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1400 题目意思:给出一个h * w的 大 矩形,需要用 1 * 2 的砖块去填充这个大矩形,问填充的方 ...

  4. HDU - 1400 Mondriaan's Dream

    HDU - 1400 思路: 轮廓线dp入门题 #include<bits/stdc++.h> using namespace std; #define fi first #define ...

  5. POJ 2411 Mondriaan&#39;s Dream

    状压DP Mondriaan's Dream Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 9938 Accepted: 575 ...

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

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

  7. POJ2411 - Mondriaan's Dream(状态压缩DP)

    题目大意 给定一个N*M大小的地板,要求你用1*2大小的砖块把地板铺满,问你有多少种方案? 题解 刚开始时看的是挑战程序设计竞赛上的关于铺砖块问题的讲解,研究一两天楞是没明白它代码是怎么写的,智商捉急 ...

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

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

  9. zoj 1100 - Mondriaan&#39;s Dream

    题目:在m*n的地板上铺上同样的1*2的地板砖,问有多少种铺法. 分析:dp,组合,计数.经典dp问题,状态压缩. 状态:设f(i,j)为前i-1行铺满,第i行铺的状态的位表示为j时的铺砖种类数: 转 ...

随机推荐

  1. CORS与JSONP的区别

    CORS与JSONP: a. JSONP只能实现GET请求,而CORS支持所有类型的HTTP请求. b. 使用CORS,开发者可以使用普通的XMLHttpRequest发起请求和获得数据,比起JSON ...

  2. Vue经典开源项目

    Vue常用的开源项目和插件库 UI组件 element ★34,784 - 饿了么出品的基于Vue2的web UI工具套件storybook ★33,503 - 响应式UI 开发及测试环境Vux ★1 ...

  3. md5如何实现encodePassword加密方法

    后台的加密代码:用户名:zhangsan   密码:123 /** * 编译密码,即加密 * @param user 用户信息 * @param password 密码 * @return 返回值为加 ...

  4. MFC 加入背景图片并让控件背景透明

    /*加入背景图片*/ BOOL CTOOLDlg::OnEraseBkgnd(CDC* pDC) {  // TODO: 在此加入消息处理程序代码和/或调用默认值  CDialog::OnEraseB ...

  5. Unsupported major.minor version 51.0问题的解决

    在java编程的过程中,当用myeclipse软件打开别人写的代码时,遇到Unsupported major.minor version 51.0此类问题,实在是令人痛苦不堪.弄了整整一晚才搞清楚,我 ...

  6. Collection 和 Collections 的差别?

    Collection 是 java.util 下的接口,它是各种集合的父接口,继承于它的 接口主要有 Set 和 List:Collections 是个 java.util 下的类.是针对集合的 帮助 ...

  7. 关于Thread的那些事

    关于Thread的那些事 1 : 你能够调用线程的实例方法Join来等待一个线程的结束.比如: public static void MainThread() { Thread t = new Thr ...

  8. UBUNTU 16.04 下安装动态链接库方法(使用ln命令可以随意映射动态库,ldd查看缺少的动态库)

    一般先使用ldd 来查看该应用程序缺少什么东西,然后,再根据sudo apt install XXX 去安装相应的动态库. 假如没有对应的库,可以使用: sudo ln -s /usr/lib/lib ...

  9. 创建一个web user control

    1.创建文件 添加,然后选择web user control 2.添加控件 在工具栏搜索button,然后拖动三个button上去 <%@ Control Language="C#&q ...

  10. Oracle RAC 实施

    第 1 步 — 确定项目范围 理由 我们实施 Oracle RAC 是为了使我们的应用程序可伸缩和高度可用,以及为我们的客户提供更可靠的服务. 目标/可交付产品 该项目的最终产品将是一个新的 Orac ...