POJ 2411Mondriaan's Dream
题目:

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

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
题意很简单就是求用1*2的小木块,有几种方法能构成h*w的长方体。
相当蛋疼的题目,可能是我比较菜吧,想了好久才找到适合DP的状态,而且状态数太多了,把内存的给爆了,迫不得以,用预处理去掉一维,内存才够用
状态的表示:
b是当前dp的矩形的宽度
dp[h][state]
h代表当前高度
state是三进制数来表示当前高度上每列的状态
2代表与当前高度同高
1代表比当前高度矮一格
0代表比当前高度矮两格
比如当
b=4
h=2
三进制2222,2221
分别代表2*4的矩形,和缺了一个角的2*4矩形
状态的转移:
为了防止出现重复的计算的情况,我们要保证状态转移的唯一性。
我想到方法是,每次操作剩下图形最高的列中最右边的列,因为这个列是唯一的,所以可以保证的转移的唯一性。
我们对这个列操作有两种
1,去掉这个两格,即去掉高2宽1的小木块
2,若这个列左边相邻的列也是与其等高的列,去掉这两个列个一格,即去掉高1宽2的小木块
代码实现:
因为这个转移方程挺复杂的,写成递推比较麻烦,所以我写成了记忆话搜索
- #include<stdio.h>
- #include<string.h>
- #include<algorithm>
- using namespace std;
- long long dp[][],ans[][];
- int u[],k[],b;
- int check(int state)
- {
- int x=state,que[]= {},i;
- for(i=; i<=; i++)
- {
- que[i]=x%;
- x/=;
- }
- for(i=; i<=; i++)
- {
- if(que[i]==)
- {
- if(que[i+]==)
- que[i+]=;
- else
- return ;
- }
- }
- return ;
- }
- long long dfs(int h,int state)
- {
- if(dp[h][state]==-)
- {
- if(h==)
- {
- dp[h][state]=check(state);/**当只剩下一列时,检查这列是否能用高1宽2的小木块组成*/
- }
- else
- {
- int x,i;
- x=state;
- for(i=; i<=b; i++)/**寻找最右边且高度与h相等的那列*/
- {
- if(x%==)
- {
- break;
- }
- x/=;
- }
- if(i>b)
- dp[h][state]=dfs(h-,state+u[b]);/**没有与h等高的列,所以h下降,扫描下一高度*/
- else
- {
- dp[h][state]=dfs(h,state-*k[i]);/**去掉高2宽1的小木块*/
- if(i<b&&(x/)%==)/**判断与x相邻列的是否也是与等高*/
- {
- dp[h][state]+=dfs(h,state-k[i]-k[i+]);/**去掉高1宽2的小木块*/
- }
- }
- }
- }
- return dp[h][state];
- }
- int main()
- {
- int i,j,len;
- u[]=;
- k[]=;
- for(i=; i<=; i++)
- {
- k[i]=k[i-]*;
- u[i]=u[i-]*+;
- }
- for(i=; i<=; i++)/**i是宽度*/
- {
- len=q[i].size();
- b=i;
- memset(dp,-,sizeof(dp));
- if(i%==)/**判断奇偶,因为若面积是奇数则坑定种类为零,不用算了*/
- {
- for(j=; j<=i; j+=)/**只算偶高度*/
- {
- ans[i][j]=dfs(j,*u[i]);
- }
- }
- else
- {
- for(j=; j<=i; j++)/**j是高度*/
- {
- ans[i][j]=dfs(j,*u[i]);
- }
- }
- }
- while(scanf("%d%d",&i,&j)&&i)
- {
- if(i<j)
- swap(i,j);
- printf("%I64d\n",ans[i][j]);
- }
- return ;
- }
POJ 2411Mondriaan's Dream的更多相关文章
- POJ:2411-Mondriaan's Dream(矩形拼接方案)
题目链接:http://poj.org/problem?id=2411 解题心得: 可以说是很经典的一个状压dp了,写dfs遍历肯定是要超时的,这个题的状态转移方程对新手来说有点吃力. 状态转移用的是 ...
- POJ 2411_Mondriaan's Dream
题意: 用1*2和2*1的方块将给定长宽的矩形填满.问有多少种放法,对称的算两种. 分析: 状态压缩dp 首先用0表示前一行没有竖块占用这个位置,而1表示该位置和他上方的位置放了一个竖块,从而压缩状态 ...
- poj 2411 Mondriaan's Dream 【dp】
题目:id=2411" target="_blank">poj 2411 Mondriaan's Dream 题意:给出一个n*m的矩阵,让你用1*2的矩阵铺满,然 ...
- POJ 2411 Mondriaan's Dream -- 状压DP
题目:Mondriaan's Dream 链接:http://poj.org/problem?id=2411 题意:用 1*2 的瓷砖去填 n*m 的地板,问有多少种填法. 思路: 很久很久以前便做过 ...
- [poj P2411] Mondriaan's Dream
[poj P2411] Mondriaan's Dream Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 18023 A ...
- POJ 2411 Mondriaan's Dream 插头dp
题目链接: http://poj.org/problem?id=2411 Mondriaan's Dream Time Limit: 3000MSMemory Limit: 65536K 问题描述 S ...
- Poj 2411 Mondriaan's Dream(压缩矩阵DP)
一.Description Squares and rectangles fascinated the famous Dutch painter Piet Mondriaan. One night, ...
- Mondriaan's Dream POJ - 2411
Mondriaan's Dream POJ - 2411 可以用状压dp,但是要打一下表.暴力枚举行.这一行的状态.上一行的状态,判断如果上一行的状态能转移到这一行的状态就转移. 状态定义:ans[i ...
- POJ 题目2411 Mondriaan's Dream(状压DP)
Mondriaan's Dream Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 13519 Accepted: 787 ...
随机推荐
- javascript 完整知识点整理
by 蔡舒啸 目录 一 5种基本类型 typeof 关键字 三种强制类型转换 日期 二 if语句for语句whiledo-whileswitch-case 比较运算符 逻辑运算符 if for语句 w ...
- 01_11_Strtus2简单数据验证
01_11_Strtus2简单数据验证 1. 引入struts标签 <%@taglib uri="/struts-tags" prefix="s" %&g ...
- Where do I belong-freecodecamp算法题目
Where do I belong(数组排序并找出元素索引) 要求 给数组排序 找到指定的值在数组的位置,并返回位置对应的索引. 思路 设定.sort()需要的返回函数 将要搜索的值添加到数组内 用. ...
- H5(一)H5与HTML、XHTML的不同
一.基本概念 html:超文本标记语言 (Hyper Text Markup Language) xhtml:可扩展超文本标记语言,是一种置标语言,表现方式与超文本标记语言(HTML)类似,不过语法上 ...
- VNC远程登录端使用经验之一
1.vnc/xmanager都是经常用的远程登录软件.vnc有个缺点就是他的进程不会自动退出比如如果开了PID1再去开PID2...PIDn.那么前面的PIDn-1个进程就会一直运行如果不手动kill ...
- 我的Python分析成长之路6
模块:本质就是.py结尾的文件.从逻辑上组织python代码. 包: 本质就是一个目录,带有__init__.py文件,从逻辑上组织模块. 模块的分类: 1.标准库(内置的模块) 2.开源库(第三方库 ...
- sqlmanagementstudio2008下载地址
http://big.wy119.com/sqlmanagementstudio2008_x86_chs.zip
- HDU 5473 There was a kingdom 凸包 DP
题意: 给出平面上n个点的坐标,选k个点,使得这k个点围起来的面积最大. 分析: 参考了 叉姐的分析 和 不慌不忙菊苣的代码 思路我都懂,但是DP的部分还是不太会写. 我体会了一下其中含义,也许这样可 ...
- Python虚拟机之异常控制流(五)
Python中的异常控制语义结构 在Python虚拟机之异常控制流(四)这一章中,我们考察了Python的异常在虚拟机中的级别上是什么东西,抛出异常这个动作在虚拟机的级别上对应的行为,最后,我们还剖析 ...
- Oralce重做日志(Redo Log)
1.简介 Oracle引入重做日志的目的:数据库的恢复. Oracle相关进程:重做日志写进程(LGWR). 重做日志性质:联机日志文件,oracle服务器运行时需要管理它们. 相关数据字典:v$lo ...