博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
POJ 2411: Mondriaan's Dream
阅读量:6897 次
发布时间:2019-06-27

本文共 939 字,大约阅读时间需要 3 分钟。

POJ 2411: Mondriaan's Dream

题目链接:

题目大意:在$h \times w$($1 \leqslant h,w \leqslant 11$)的网格中放满$1 \times 2$的木条,问有几种放置方案。

状压dp

定义横向放置的木条为$11$(横向),纵向放置的木条为$_1^0$(纵向).

这样检查转移的合法性只需要检查前一行状态$s_{i-1}$与当前行状态$s_i$的位或($s_{i-1}|s_i$)是否全为$1$,且横向的$1$是否均匹配.

定义状态$dp[i][s]$表示第$i$行状态为$s$的方案数,若状态$s_{i-1}$由状态$s_i$转移合法,则有$dp[i][s_{i-1}]+=dp[i-1][s_i]$.

最后一行不能放置向下的纵向木条,即最后一行全为$1$,故$ans=dp[n-1][(1<<m)-1]$.

可以预处理合法的状态并标记以降低复杂度。

总时间复杂度为$O(2^{MAX\{m\}}+n2^{2m})$.

代码如下:

1 #include 
2 #include
3 using namespace std; 4 typedef long long ll; 5 int n,m; 6 ll dp[15][1<<11]; 7 bool s[1<<11]; 8 bool valid(int s){ 9 int tot=0;10 while(s){11 if(s&1)tot++;12 else if(tot&1)return 0;13 s>>=1;14 }15 return tot%2==0;16 }17 void init(){18 for(int i=0;i<(1<<11);++i)19 s[i]=valid(i);20 }21 bool check(int x,int y){22 if((x|y)+1!=(1<

 

转载于:https://www.cnblogs.com/barrier/p/6769657.html

你可能感兴趣的文章
OpenMNS--管理网络的绝好工具
查看>>
ORACLE LINUX 6.1安装过程
查看>>
iPhone/Mac Objective-C内存管理原理
查看>>
整理Silverlight资源列表(三)-SL实际运用案例
查看>>
02-BGP选路原则和属性详解--weight
查看>>
7.[数据结构和算法分析笔记]词典 Dictionary
查看>>
CCNP精粹系列之八----帧中继全网拓扑试验配置
查看>>
Lync升级S4B秘籍,So Easy!!!
查看>>
SpringBoot整合mybatis、shiro、redis实现基于数据库的细粒度动态权限管理系统实例...
查看>>
android用户界面-组件Widget-进度条ProgressBar
查看>>
猜字谜小游戏编程
查看>>
【OneNote Mobile】 如何处理便签内容的格式?
查看>>
Algeco Scotsman将召开2016年第三季度业绩电话会议
查看>>
新加坡IMDA计划进行Li-Fi测试
查看>>
《深入理解大数据:大数据处理与编程实践》一一1.3 MapReduce并行计算技术简介...
查看>>
LoadRunner关联的高级应用
查看>>
如何减少返工工作量?
查看>>
《敏捷可执行需求说明 Scrum提炼及实现技术》—— 2.1 界定不可更改的边界
查看>>
关注安防行业 聚焦公共安防系统
查看>>
Android代码(Handler的运用),HttpURLConnection的应用,将url图片地址转换成图片。...
查看>>