用1 ×2 的瓷砖覆盖8 ×8 的地板,有多少种方式呢?
来源:互联网 发布:sencha ext js 编辑:程序博客网 时间:2024/05/17 07:01
这个题在POJ上有,地址是:http://acm.pku.edu.cn/JudgeOnline/problem?id=2411
以前做过这个题,是用状态DP来做的。大致说下方法,DP需要用到两维,一维表示到达哪一行,另一维表示这一行的状态。
用二进制来表示
假定方格为N行M列。
表示方法如下:
f[i][j]。 ---- i表示第i行,j表示该行的二进制状态。而f[i][j]则记录由i,j构成的状态有多少种摆法。
我举个例子,假定总共有4行5列。
如下状态: *号表示被铺了方块,0表示尚未被铺方块。
*****
*0**0
00000
00000
可以看到第2行的状态为*0**0,即用二进制来表示就是10110,即 f[2][22] 来表示。(当然,行号也可以从0开始计)
以上是状态表示方法,有了状态表示方法以后就需要得到一个进行状态转移的递推式。
考虑i行j列的那个格子,有3种状态,第一种是由第i-1行j列铺上来,第二种是 在本行内,与相邻的格子铺的瓷砖,第三种该格子留空,以备下一行来使用。
枚举这一行的格子的每一种状态,即可以得到所需的上一行状态。
举例来说,枚举一个如下状态(*表示该格子是已经被填充的,-表示空格子,其余数字均表示2*1的瓷砖摆法):
1***3**
1-22344
可知本行的状态为 1011111,生成该状态所需要的上一行状态为,0111011。因为只有这样才能满足瓷砖1和瓷砖3的嵌入且又不会留下空格子。
因此可以由本状态进行一次累加:用二进制表示第二维 即 a[i][1011111] += a[i-1][0111011]。
那么,最后 a[N][(1<<M)- 1]即为所得。
POJ的这题的代码(几年前写的,风格很烂,见笑了):
2953784 zyl072 2411 Accepted 7844K 124MS G++ 1222B 2007-11-29 10:22:08
以前做过这个题,是用状态DP来做的。大致说下方法,DP需要用到两维,一维表示到达哪一行,另一维表示这一行的状态。
用二进制来表示
假定方格为N行M列。
表示方法如下:
f[i][j]。 ---- i表示第i行,j表示该行的二进制状态。而f[i][j]则记录由i,j构成的状态有多少种摆法。
我举个例子,假定总共有4行5列。
如下状态: *号表示被铺了方块,0表示尚未被铺方块。
*****
*0**0
00000
00000
可以看到第2行的状态为*0**0,即用二进制来表示就是10110,即 f[2][22] 来表示。(当然,行号也可以从0开始计)
以上是状态表示方法,有了状态表示方法以后就需要得到一个进行状态转移的递推式。
考虑i行j列的那个格子,有3种状态,第一种是由第i-1行j列铺上来,第二种是 在本行内,与相邻的格子铺的瓷砖,第三种该格子留空,以备下一行来使用。
枚举这一行的格子的每一种状态,即可以得到所需的上一行状态。
举例来说,枚举一个如下状态(*表示该格子是已经被填充的,-表示空格子,其余数字均表示2*1的瓷砖摆法):
1***3**
1-22344
可知本行的状态为 1011111,生成该状态所需要的上一行状态为,0111011。因为只有这样才能满足瓷砖1和瓷砖3的嵌入且又不会留下空格子。
因此可以由本状态进行一次累加:用二进制表示第二维 即 a[i][1011111] += a[i-1][0111011]。
那么,最后 a[N][(1<<M)- 1]即为所得。
POJ的这题的代码(几年前写的,风格很烂,见笑了):
- C/C++ code
- #include <stdio.h>#include <string.h>long long s[14][14][5000];int w,h;int list[20],v[20];void GetList(int step){ if (step>w){ int value1=0; int value2=0; int i; for (i=1;i<=w;i++){ value1<<=1; value2<<=1; switch (list[i]){ case 0: value1|=1; break; case 1: value1|=1; value2|=1; break; case 2: value2|=1; break; } } if (h>1) s[w][h][value2]+=s[w][h-1][value1]; else s[w][h][value2]=1; return; } if (h>1) list[step]=2,GetList(step+1); if (step<w) list[step]=list[step+1]=1,GetList(step+2); list[step]=0; GetList(step+1); }int main(){ memset(s,0,sizeof s); int i,j,k; v[0]=1; for (i=1;i<20;i++) v[i]=v[i-1]<<1; for (w=1;w<=12;w++) for (h=1;h<=12;h++) GetList(1); for (scanf("%d%d",&w,&h);w;scanf("%d%d",&w,&h)) printf("%I64d\n",s[w][h][v[w]-1]);}
2953784 zyl072 2411 Accepted 7844K 124MS G++ 1222B 2007-11-29 10:22:08
有点需要说明,由于这题的测试数据很多,因此我不是每次输入后重新计算,而是选择了一次性把所有可能输入的结果全部算完。。然后再输入后就可以直接输出结果。这样做在测试数据很多的情况下可以避免很多重复运算。因此我的DP状态是用三维来表示的,分别是 行、列、当前行状态。
转载:http://topic.csdn.net/u/20100621/16/74D19159-8921-4405-8028-73B348755716.html
(郁闷 看不懂 先转着吧)
- 用1 ×2 的瓷砖覆盖8 ×8 的地板,有多少种方式呢?
- 用1 ×2 的瓷砖覆盖8 ×8 的地板,有多少种方式呢?
- 用1 ×2 的瓷砖覆盖8 ×8 的地板,有多少种方式呢?
- 求用1×2的瓷砖覆盖2×M(M为正整数)的地板的方法数 (第二题)
- 1*2瓷砖铺满足8*8地板
- 瓷砖覆盖地板问题
- 瓷砖覆盖地板
- 瓷砖覆盖地板问题
- 瓷砖覆盖地板
- 瓷砖覆盖地板
- 瓷砖覆盖地板
- [编程之美] 瓷砖覆盖地板
- 编程之美4.2 瓷砖覆盖地板
- 用任意多个个2*1的小矩形,覆盖2*n的大矩形,请问有多少种覆盖的方法?
- 读书笔记之编程之美 - 4.2 瓷砖覆盖地板
- poj 2411 & 编程之美 4.2 瓷砖覆盖地板
- poj 2411 编程之美-瓷砖覆盖地板
- 编程之美 4.2 瓷砖覆盖地板 扩展问题
- 5款手机通讯录同步工具
- 在PC环境下用VS2005编译供Windows使用的libpng和zlib库
- jsp下显示硬盘下绝对路径下的中文文件名的图片
- Vim记忆上次编辑的位置
- JAVA项目经验--程序员成长的关键
- 用1 ×2 的瓷砖覆盖8 ×8 的地板,有多少种方式呢?
- mini2440之首个C程序点亮LED分析
- java.util.Date与java.sql.Date之间的区别和转化
- 软件正在改变世界,为什么程序员却得不到足够的尊重?
- uvaoj 457
- hibernate4 替代hibernate3 的Hibernate.INTEGER的用法
- android 开发之物理设备连接
- 一道收集优惠券的面试题
- 从历史学习的 8 堂架构课