骨牌铺方格的多种做法
来源:互联网 发布:mysql now 前一天 编辑:程序博客网 时间:2024/05/30 04:11
应对题目:用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;}
1 0
- 骨牌铺方格的多种做法
- HDU2046 骨牌铺方格
- HDOJ2046 骨牌铺方格
- 2046 骨牌铺方格
- 2046 骨牌铺方格
- 骨牌铺方格
- hdu2046 骨牌铺方格
- 骨牌铺方格
- 骨牌铺方格
- hdoj_2046 骨牌铺方格
- 骨牌铺方格
- 骨牌铺方格2
- hdu 骨牌铺方格
- 骨牌铺方格
- 骨牌铺方格
- 骨牌铺方格(sdut1018
- 骨牌铺方格
- 骨牌铺方格
- Can you give a visual explanation for the back propagation algorithm for neural networks?
- 【总结】延时程序
- PMP考试总结
- shell中的if-then语句
- Tapestry5项目的导入
- 骨牌铺方格的多种做法
- 获取相册照片的绝对路径
- 关于Laravel简易路由操作的体会
- R语言-简单多元回归
- Android学习笔记2-HttpUtil工具类
- 启动eclipse时,出现以下错误:发现了以元素 'd:skin' 开头的无效内容,此处不应含有子元素。
- 嵌入式lab4——Bootloader
- Getting And Cleaning Data Week 3 Quiz
- 10008---linux 添加用户、权限