骨牌铺方格的3种做法
应对题目:用1*2的骨牌铺满n*m的矩形总共有多种方法
方法1:状压DP:
复杂度:n*m*(2^m)
解题过程:
1、为了提高效率,我们规定m=<n,如果n>m就交换
2、以单个格子作为每个阶段,递推方向为从左上到右下,每个阶段储存前m个方块的状态,1表示已覆盖,0表示未覆盖
3、阶段决策是:"以当前格子为右下角,要不要放骨牌以及放哪种骨牌",答案有3种:不放骨牌、放竖骨牌、放横骨牌,其中①不放骨牌要求上面的格子必须被覆盖,即k&(1<<(m-1))==1②放竖骨牌要求上面的格子必须没有被覆盖且且不能是第一行,即i!=1 && (k&(1<<(m-1)))==0③放横骨牌要求上面的格子必须被覆盖且左边的格子必须没有被覆盖还不能是第一列,即j!=1 && (k&(1<<(m-1)))!=0 && (k&1)==0
缺点:复杂度略高
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
int n, m, cur;
long long dp[2][1<<15]; /*1表示当前位置已被填上,0则相反*/
int main(void)
{int i, j, k;while(scanf("%d%d", &n, &m), n!=0 || m!=0){for(i=0;i<=(1<<m)-1;i++)dp[0][i] = 1; /*边界处理,所有dp[0][j]初始化为1*/if(m>n)swap(n, m); /*交换行列,使列尽可能窄*/cur = 0;for(i=1;i<=n;i++){for(j=1;j<=m;j++){if(cur==0) /*滚动数组*/cur = 1;elsecur = 0; memset(dp[cur], 0, sizeof(dp[cur]));for(k=0;k<=(1<<m)-1;k++) // 枚举上个阶段的状态(00000000…(m个0)→11111111…(m个1)){/*第一种放法:不放 条件:二进制k最左边为1,即k&(1<<(m-1))==1*/if(k&(1<<(m-1))) dp[cur][(k<<1)^(1<<m)] += dp[1-cur][k]; //(k<<1)^(1<<m)为新状态,所有1和0往左移1位并弃掉最高位的1,因为不放所以不用+1*//*第二种放法:竖放 条件:二进制k最左边为0且当前不是第一行,即k&(1<<(m-1))==0 && i!=1 */if(i!=1 && (k&(1<<(m-1)))==0)dp[cur][(k<<1)+1] += dp[1-cur][k]; //(k<<1)+1为新状态,所有1和0往左移一位并+1, 因为最高位是0没必要弃掉/*第三种放法:横放 条件:二进制k最左边为1,最右边为0,且当前不是第一列,即(k&(1<<(m-1)))!=0 && (k&1)==0 && j!=1)*/if(j!=1 && (k&(1<<(m-1)))!=0 && (k&1)==0)dp[cur][(k<<1)^(1<<m)+3] += dp[1-cur][k]; //(k<<1)^(1<<m)+3为新状态,所有1和0往左移一位并+3,弃掉最高位的1}}}printf("%lld\n", dp[cur][(1<<m)-1]); //全部填满的状态}return 0;
}
方法2:公式:
https://en.wikipedia.org/wiki/Domino_tiling#CITEREFKasteleyn1961
复杂度:n*m
缺点:无法取模
#include<stdio.h>
#include<math.h>
#define PI acos(-1.0)
int main(void)
{double n, m, sum;int i, j;while(scanf("%lf%lf", &n, &m), n!=0 || m!=0){sum = 1;for(i=1;i<=(m+1)/2;i++){for(j=1;j<=(n+1)/2;j++)sum *= 4*cos(PI*i/(m+1))*cos(PI*i/(m+1))+4*cos(PI*j/(n+1))*cos(PI*j/(n+1));}printf("%.0f\n", sum);}return 0;
}
方法3:矩阵快速幂:
详见http://blog.csdn.net/jaihk662/article/details/77750353
骨牌铺方格的3种做法相关推荐
- hdu 2046 骨牌铺方格 递推求解
骨牌铺方格 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Subm ...
- HDOJ 2046 骨牌铺方格 【递推】
HDOJ 2046 骨牌铺方格 [递推] 题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=2046 铺2*1只有一种情况(一竖) 2*2有两种情况(两横或 ...
- 骨牌铺方格(递归问题)
骨牌铺方格 Problem Description 在2×n的一个长方形方格中,用一个1× 2的骨牌铺满方格,输入n ,输出铺放方案的总数. 例如n=3时,为2× 3方格,骨牌的铺放方案有三种,如下图 ...
- HDU 2046 骨牌铺方格【递推】
骨牌铺方格 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Subm ...
- HDU2046 骨牌铺方格【递推】
骨牌铺方格 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Subm ...
- 骨牌铺方格java_[ACM_HDU_2046]骨牌铺方格 | 学步园
骨牌铺方格 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submiss ...
- HDU 2046 骨牌铺方格 递推
骨牌铺方格 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Subm ...
- 骨牌铺方格(HDU-2046)
Problem Description 在2×n的一个长方形方格中,用一个1× 2的骨牌铺满方格,输入n ,输出铺放方案的总数. 例如n=3时,为2× 3方格,骨牌的铺放方案有三种,如下图: Inpu ...
- HDU_oj_2046 骨牌铺方格
Problem Description 在2×n的一个长方形方格中,用一个1× 2的骨牌铺满方格,输入n ,输出铺放方案的总数. 例如n=3时,为2× 3方格,骨牌的铺放方案有三种,如下图: Inpu ...
最新文章
- 科大星云诗社动态20210518
- Android之BottomNavigationView实现底部按钮水纹波效果
- java面试题三_最全的java面试题目三
- 微型计算机在温室管理中的应用初探,文献综述-测控051-陈杰.doc
- android 时间计划软件,时间规划局专业版
- 轻量级linux iso,antiX 17.2 发布,基于Debian的轻量级Linux发行版
- MySQL5.7安装教程(windows .zip)
- android bugly 错误分析,使用 Robolectric 单元测试运行时 bugly 初始化异常
- grid网格布局基础(一)
- cad计算机忘了保存,cad图纸没保存怎么恢复(电脑突然断电,怎么找回未保存的CAD?)...
- QNX系统将C/C++代码编译为lib***.so文件
- pacman系列命令
- Redhat克隆及其配置
- 新松机器人招股说明书_来看看绿的谐波招股书披露的重要信息
- vue中改变v-html元素样式
- PS---星空名片制作教程
- 常用电脑硬件检测工具下载
- 华为南研所2015年面试经历总结
- NewStarCTF 公开赛赛道-WEEK1|REVERSE
- 【kafka源码】/log_dir_event_notification的LogDir脱机事件通知
热门文章
- p语言是python吗-Python 这语言真是混乱和原始
- 三星Bixby如此人性 小娜的下一步就是善解人意
- VB589语音识别芯片开发
- libreoffice 开发文档_LibreOffice中文 | linux软件
- 二级 办公软件高级应用技术_塔河县(局)工会举办电脑办公应用技术培训班...
- cas5.3 → 连接mysql数据库
- 【数组】牛客网:调整数组顺序使奇数位于偶数前面(一)
- 【蓝桥杯】蓝桥杯日期类问题总结
- FFmpeg源代码简单分析:内存的分配和释放(av_malloc()、av_free()等)
- python中隔行输出_在Python中的分隔行上打印列表元素