编程之美 4.2 瓷砖覆盖地板 扩展问题
来源:互联网 发布:utorrent for linux 编辑:程序博客网 时间:2024/04/29 01:22
原帖: http://blog.csdn.net/limchiang/article/details/8619611
题意:
用 1 * 2 的瓷砖覆盖 n * m 的地板,问共有多少种覆盖方式?
思路:
用2进制的01表示不放还是放,第i行只和i-1行有关,枚举i-1行的每个状态,推出由此状态能达到的i行状态:如果i-1行的出发状态某处未放,必然要在i行放一个竖的方块,所以我对上一行状态按位取反之后的状态就是放置了竖方块的状态。
然后用dfs搜索在i行放横着的方块的所有可能,并且把这些状态累加上i-1的出发状态的方法数,如果该方法数为0,直接continue。
状态压缩DP
dp[i][j]表示第i行状态为j时有多少种方法,
e.g. m=6, i=1, j=15,意味着 第一行瓷砖的状态为 0 0 1 1 1 1. (后四列横向放置了2个瓷砖,但是前2列没放)
那么i=2,第二行瓷砖状态必须是 1 1 x x x x. (x意味着可以放也可以不放,但是前2列状态必须是1, 1 (放置2个竖向瓷砖,以填补第一列的空缺)
#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;}
0 0
- 编程之美 4.2 瓷砖覆盖地板 扩展问题
- 编程之美4.2 瓷砖覆盖地板
- [编程之美] 瓷砖覆盖地板
- 读书笔记之编程之美 - 4.2 瓷砖覆盖地板
- poj 2411 & 编程之美 4.2 瓷砖覆盖地板
- poj 2411 编程之美-瓷砖覆盖地板
- Mondriaan's Dream 瓷砖覆盖地板 编程之美
- 编程之美:第四章 数字之趣 4.2瓷砖覆盖地板
- 瓷砖覆盖地板问题
- 瓷砖覆盖地板问题
- 编程之美4.2 瓷砖覆盖
- 状态压缩动态规划 POJ 2411 (编程之美-瓷砖覆盖地板)
- 状态压缩与动态规划(DP)---编程之美---瓷砖覆盖地板---POJ2411
- 状态压缩动态规划 POJ 2411 (编程之美-瓷砖覆盖地板)
- 瓷砖覆盖地板
- 瓷砖覆盖地板
- 瓷砖覆盖地板
- 瓷砖覆盖地板
- iOS中防止多个按钮同时点击出现的问题
- 如何理解“可靠性”和“可用性”?
- 【最短路算法模板】
- kmemleak 内存泄露检测
- ViewPager循环效果
- 编程之美 4.2 瓷砖覆盖地板 扩展问题
- xcode 调试的时候不显示 c 变量值
- HDU 4607 Park Visit【树的直径】
- leetcode 刷题之路 58 Linked List Cycle
- hone hone clock
- 从简入难makefile文件编写,Linux C++编程,简单vi命令
- 浅谈C中的malloc和free
- A Simple Problem with Integers - POJ 3468 线段树
- 线程的创建状态