poj 2411 & 编程之美 4.2 瓷砖覆盖地板
来源:互联网 发布:科研软件 编辑:程序博客网 时间:2024/04/28 16:53
题目链接
题意:用 1 * 2 的瓷砖覆盖 n * m 的地板,问共有多少种覆盖方式?
思路:用2进制的01表示不放还是放,第i行只和i-1行有关,枚举i-1行的每个状态,推出由此状态能达到的i行状态:如果i-1行的出发状态某处未放,必然要在i行放一个竖的方块,所以我对上一行状态按位取反之后的状态就是放置了竖方块的状态。然后用dfs搜索在i行放横着的方块的所有可能,并且把这些状态累加上i-1的出发状态的方法数,如果该方法数为0,直接continue。
- #include <stdio.h>
- #include <string.h>
- /** n * m 的地板 */
- int n,m;
- /** dp[i][j] = x 表示使第i 行状态为j 的方法总数为x */
- __int64 dp[12][2049];
- /* 该方法用于搜索某一行的横向放置瓷砖的状态数,并把这些状态累加上row-1 行的出发状态的方法数
- * @name row 行数
- * @name state 由上一行决定的这一行必须放置竖向瓷砖的地方,s的二进制表示中的1 就是这些地方
- * @name pos 列数
- * @name pre_num row-1 行的出发状态为~s 的方法数
- */
- void dfs( int row, int state, int pos, __int64 pre_num )
- {
- /** 到最后一列 */
- if( pos == m ){
- dp[row][state] += pre_num;
- return;
- }
- /** 该列不放 */
- dfs( row, state, pos + 1, pre_num );
- /** 该列和下一列放置一块横向的瓷砖 */
- if( ( pos <= m-2 ) && !( state & ( 1 << pos ) ) && !( state & ( 1 << ( pos + 1 ) ) ) )
- dfs( row, state | ( 1 << pos ) | ( 1 << ( pos + 1 ) ), pos + 2, pre_num );
- }
- int main()
- {
- while( scanf("%d%d",&n,&m) && ( n || m ) ){
- /** 对较小的数进行状压,已提高效率 */
- if( n < m ){
- n=n^m;
- m=n^m;
- n=n^m;
- }
- memset( dp, 0, sizeof( dp ) );
- /** 初始化第一行 */
- dfs( 1, 0, 0, 1 );
- for( int i = 2; i <= n; i ++ )
- for( int j = 0; j < ( 1 << m ); j ++ ){
- if( dp[i-1][j] ){
- __int64 tmp = dp[i-1][j];
- /* 如果i-1行的出发状态某处未放,必然要在i行放一个竖的方块,
- * 所以我对上一行状态按位取反之后的状态就是放置了竖方块的状态
- */
- dfs( i, ( ~j ) & ( ( 1 << m ) - 1 ), 0, tmp ) ;
- }
- else continue;
- }
- /** 注意并不是循环i 输出 dp[n][i]中的最大值 */
- printf( "%I64d\n",dp[n][(1<<m)-1] );
- }
- return 0;
- }
扩展:
用p*q的瓷砖能覆盖M*N的地板的充要条件是:(这是一个判定问题,并不需要求方法数)1。第一行和第一列可以被覆盖2。m或n可以被p整除并且m或n可以被q整除
简单证明:
①当m(或n)被p 整除 & n(或m)被q 整除时,易知,一定能覆盖(一行行覆盖)
②当m(或n)被p * q 整除时,只要第一行的n 个格子能被覆盖,则一定能覆盖
③当①与②都不满足时,根据面积易知一定不能覆盖
更详细的参见下面的slides:http://www-math.mit.edu/~rstan/transparencies/tilings.pdf
0 0
- poj 2411 & 编程之美 4.2 瓷砖覆盖地板
- poj 2411 编程之美-瓷砖覆盖地板
- 编程之美4.2 瓷砖覆盖地板
- [编程之美] 瓷砖覆盖地板
- 读书笔记之编程之美 - 4.2 瓷砖覆盖地板
- 编程之美 4.2 瓷砖覆盖地板 扩展问题
- 状态压缩动态规划 POJ 2411 (编程之美-瓷砖覆盖地板)
- 状态压缩动态规划 POJ 2411 (编程之美-瓷砖覆盖地板)
- Mondriaan's Dream 瓷砖覆盖地板 编程之美
- 编程之美:第四章 数字之趣 4.2瓷砖覆盖地板
- 编程之美4.2 瓷砖覆盖
- 状态压缩与动态规划(DP)---编程之美---瓷砖覆盖地板---POJ2411
- 瓷砖覆盖地板问题
- 瓷砖覆盖地板
- 瓷砖覆盖地板问题
- 瓷砖覆盖地板
- 瓷砖覆盖地板
- 瓷砖覆盖地板
- C++快捷键
- 消息队列RabbitMQ入门介绍
- linux进程调度策略
- const char*的问题
- Raysoft.Framework.Accounts.AccountsHelper
- poj 2411 & 编程之美 4.2 瓷砖覆盖地板
- oracle查看当前用户权限
- 判断访问网页是否为移动设备 不同类型设备跳转至不同链接地址
- MySQL性能优化的最佳20+条经验
- sicily 1443.Printer Queue
- SP-0042 unknow command "$impdp"
- cf——C. Triangle(三角形的顶点)
- ssh常用用法小结
- 【Adnroid】adb remount 提示:Operation not permitted