题目:

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. 1 2
  2. 1 3
  3. 1 4
  4. 2 2
  5. 2 3
  6. 2 4
  7. 2 11
  8. 4 11
  9. 0 0

Sample Output

  1. 1
  2. 0
  3. 1
  4. 2
  5. 3
  6. 5
  7. 144
  8. 51205
    题意很简单就是求用1*2的小木块,有几种方法能构成h*w的长方体。
    相当蛋疼的题目,可能是我比较菜吧,想了好久才找到适合DP的状态,而且状态数太多了,把内存的给爆了,迫不得以,用预处理去掉一维,内存才够用
    状态的表示:
    b是当前dp的矩形的宽度
    dp[h][state]
    h代表当前高度
    state是三进制数来表示当前高度上每列的状态
    2代表与当前高度同高
    1代表比当前高度矮一格
    0代表比当前高度矮两格
    比如当
    b=4
    h=2
    三进制22222221
    分别代表2*4的矩形,和缺了一个角的2*4矩形
    状态的转移:
    为了防止出现重复的计算的情况,我们要保证状态转移的唯一性。
    我想到方法是,每次操作剩下图形最高的列中最右边的列,因为这个列是唯一的,所以可以保证的转移的唯一性。
    我们对这个列操作有两种
    1,去掉这个两格,即去掉高21的小木块
    2,若这个列左边相邻的列也是与其等高的列,去掉这两个列个一格,即去掉高12的小木块
    代码实现:
    因为这个转移方程挺复杂的,写成递推比较麻烦,所以我写成了记忆话搜索
  1. #include<stdio.h>
  2. #include<string.h>
  3. #include<algorithm>
  4. using namespace std;
  5. long long dp[][],ans[][];
  6. int u[],k[],b;
  7. int check(int state)
  8. {
  9. int x=state,que[]= {},i;
  10. for(i=; i<=; i++)
  11. {
  12. que[i]=x%;
  13. x/=;
  14. }
  15. for(i=; i<=; i++)
  16. {
  17. if(que[i]==)
  18. {
  19. if(que[i+]==)
  20. que[i+]=;
  21. else
  22. return ;
  23. }
  24. }
  25. return ;
  26. }
  27. long long dfs(int h,int state)
  28. {
  29. if(dp[h][state]==-)
  30. {
  31. if(h==)
  32. {
  33. dp[h][state]=check(state);/**当只剩下一列时,检查这列是否能用高1宽2的小木块组成*/
  34. }
  35. else
  36. {
  37. int x,i;
  38. x=state;
  39. for(i=; i<=b; i++)/**寻找最右边且高度与h相等的那列*/
  40. {
  41. if(x%==)
  42. {
  43. break;
  44. }
  45. x/=;
  46. }
  47. if(i>b)
  48. dp[h][state]=dfs(h-,state+u[b]);/**没有与h等高的列,所以h下降,扫描下一高度*/
  49. else
  50. {
  51. dp[h][state]=dfs(h,state-*k[i]);/**去掉高2宽1的小木块*/
  52. if(i<b&&(x/)%==)/**判断与x相邻列的是否也是与等高*/
  53. {
  54. dp[h][state]+=dfs(h,state-k[i]-k[i+]);/**去掉高1宽2的小木块*/
  55. }
  56. }
  57. }
  58. }
  59. return dp[h][state];
  60. }
  61. int main()
  62. {
  63. int i,j,len;
  64. u[]=;
  65. k[]=;
  66. for(i=; i<=; i++)
  67. {
  68. k[i]=k[i-]*;
  69. u[i]=u[i-]*+;
  70. }
  71. for(i=; i<=; i++)/**i是宽度*/
  72. {
  73. len=q[i].size();
  74. b=i;
  75. memset(dp,-,sizeof(dp));
  76. if(i%==)/**判断奇偶,因为若面积是奇数则坑定种类为零,不用算了*/
  77. {
  78. for(j=; j<=i; j+=)/**只算偶高度*/
  79. {
  80. ans[i][j]=dfs(j,*u[i]);
  81. }
  82. }
  83. else
  84. {
  85. for(j=; j<=i; j++)/**j是高度*/
  86. {
  87. ans[i][j]=dfs(j,*u[i]);
  88. }
  89. }
  90. }
  91. while(scanf("%d%d",&i,&j)&&i)
  92. {
  93. if(i<j)
  94. swap(i,j);
  95. printf("%I64d\n",ans[i][j]);
  96. }
  97. return ;
  98. }
  1.  

POJ 2411Mondriaan's Dream的更多相关文章

  1. POJ:2411-Mondriaan's Dream(矩形拼接方案)

    题目链接:http://poj.org/problem?id=2411 解题心得: 可以说是很经典的一个状压dp了,写dfs遍历肯定是要超时的,这个题的状态转移方程对新手来说有点吃力. 状态转移用的是 ...

  2. POJ 2411_Mondriaan's Dream

    题意: 用1*2和2*1的方块将给定长宽的矩形填满.问有多少种放法,对称的算两种. 分析: 状态压缩dp 首先用0表示前一行没有竖块占用这个位置,而1表示该位置和他上方的位置放了一个竖块,从而压缩状态 ...

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

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

  4. POJ 2411 Mondriaan's Dream -- 状压DP

    题目:Mondriaan's Dream 链接:http://poj.org/problem?id=2411 题意:用 1*2 的瓷砖去填 n*m 的地板,问有多少种填法. 思路: 很久很久以前便做过 ...

  5. [poj P2411] Mondriaan's Dream

    [poj P2411] Mondriaan's Dream Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 18023   A ...

  6. POJ 2411 Mondriaan's Dream 插头dp

    题目链接: http://poj.org/problem?id=2411 Mondriaan's Dream Time Limit: 3000MSMemory Limit: 65536K 问题描述 S ...

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

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

  8. Mondriaan's Dream POJ - 2411

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

  9. POJ 题目2411 Mondriaan's Dream(状压DP)

    Mondriaan's Dream Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 13519   Accepted: 787 ...

随机推荐

  1. javascript 完整知识点整理

    by 蔡舒啸 目录 一 5种基本类型 typeof 关键字 三种强制类型转换 日期 二 if语句for语句whiledo-whileswitch-case 比较运算符 逻辑运算符 if for语句 w ...

  2. 01_11_Strtus2简单数据验证

    01_11_Strtus2简单数据验证 1. 引入struts标签 <%@taglib uri="/struts-tags" prefix="s" %&g ...

  3. Where do I belong-freecodecamp算法题目

    Where do I belong(数组排序并找出元素索引) 要求 给数组排序 找到指定的值在数组的位置,并返回位置对应的索引. 思路 设定.sort()需要的返回函数 将要搜索的值添加到数组内 用. ...

  4. H5(一)H5与HTML、XHTML的不同

    一.基本概念 html:超文本标记语言 (Hyper Text Markup Language) xhtml:可扩展超文本标记语言,是一种置标语言,表现方式与超文本标记语言(HTML)类似,不过语法上 ...

  5. VNC远程登录端使用经验之一

    1.vnc/xmanager都是经常用的远程登录软件.vnc有个缺点就是他的进程不会自动退出比如如果开了PID1再去开PID2...PIDn.那么前面的PIDn-1个进程就会一直运行如果不手动kill ...

  6. 我的Python分析成长之路6

    模块:本质就是.py结尾的文件.从逻辑上组织python代码. 包: 本质就是一个目录,带有__init__.py文件,从逻辑上组织模块. 模块的分类: 1.标准库(内置的模块) 2.开源库(第三方库 ...

  7. sqlmanagementstudio2008下载地址

    http://big.wy119.com/sqlmanagementstudio2008_x86_chs.zip

  8. HDU 5473 There was a kingdom 凸包 DP

    题意: 给出平面上n个点的坐标,选k个点,使得这k个点围起来的面积最大. 分析: 参考了 叉姐的分析 和 不慌不忙菊苣的代码 思路我都懂,但是DP的部分还是不太会写. 我体会了一下其中含义,也许这样可 ...

  9. Python虚拟机之异常控制流(五)

    Python中的异常控制语义结构 在Python虚拟机之异常控制流(四)这一章中,我们考察了Python的异常在虚拟机中的级别上是什么东西,抛出异常这个动作在虚拟机的级别上对应的行为,最后,我们还剖析 ...

  10. Oralce重做日志(Redo Log)

    1.简介 Oracle引入重做日志的目的:数据库的恢复. Oracle相关进程:重做日志写进程(LGWR). 重做日志性质:联机日志文件,oracle服务器运行时需要管理它们. 相关数据字典:v$lo ...