☆ [POJ2411] Mondriaan's Dream 「状压DP」
传送门 >Here<
题意:用1*2的砖块铺满n*m的地板有几种方案
思路分析
状压经典题!
我们以$f[i][j]$作为状态,表示第i行之前全部填完并且第i行状态为j(状压)时的方案数。
我们考虑,对于一个格子,一块砖有3种方法。
(一):横着放。对下一行没有任何影响
(二):竖着放,并且当前这一格作为砖块的下层。那么对下一行也没有任何影响
(三):竖着放,并且当前这一格作为砖块的上层。这种情况对下一行很明显是有影响的。
综上,只有情况3是对下一行有影响的。
所以我们需要一种方法来区分前两种情况和第三种情况。
对于第一种情况,我们把横着的两个位置都染上1,第二种情况的所在格子染成1。唯有第三种情况的时候把当前格子染成0.
所以基本思路就有了,枚举行,然后枚举上下两个状态进行状态转移。如果这两种状态能够吻合(即不冲突),就累计方案数。
那么怎么进行判断是否冲突呢?
首先,一上一下不能再同一个位置出现0——因为这就意味着有两个竖放砖块的上层。
另外,如果一上一下都是1,意味着是两个横放砖块——相邻的两个格子也必须是1.
这样做单独一个的复杂度是4千万左右不会爆,但是考虑到题目有多组询问……打表就好了。
Code
这个代码是表的生成器。
/*By QiXingzhi*/
#include <cstdio>
#include <cstring>
using namespace std;
typedef long long ll;
#define int ll
const int N = ;
const int INF = ;
int h,w,lim;
int f[][N];
inline bool Check(int lst, int cur, int m){
for(int i = ; i < m;){
if(!(lst & ( << (i))) && !(cur & ( << (i)))) return ;
else if((lst & ( << (i))) && (cur & ( << (i)))){
if((lst & ( << (i+))) && (cur & ( << (i+)))){ i += ; continue; }
else return ;
}
else{ ++i; continue; }
}
return ;
}
inline int solve(int n, int m){
memset(f, , sizeof(f));
lim = ((<<(m))-);
f[][lim] = ;
for(int i = ; i <= n; ++i)
for(int j = ; j <= lim; ++j)
if(i == ){ if(Check(lim, j, m)) ++f[][j]; }
else{ for(int k = ; k <= lim; ++k) if(Check(k, j, m)) f[i][j] += f[i-][k]; }
return f[n][lim];
}
main(){
while(){
scanf("%d %d", &h, &w);
if(!h && !w) break;
if((h & ) && (w & )){ printf("0\n"); continue; }
printf("%lld\n",solve(h,w));
}
return ;
}
☆ [POJ2411] Mondriaan's Dream 「状压DP」的更多相关文章
- [Poj2411]Mondriaan's Dream(状压dp)(插头dp)
Mondriaan's Dream Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 18096 Accepted: 103 ...
- poj2411 Mondriaan's Dream[简单状压dp]
$11*11$格子板上铺$1*2$地砖方案.以前做过?权当复习算了,毕竟以前学都是浅尝辄止的..常规题,注意两个条件:上一行铺竖着的则这一行同一位一定要铺上竖的,这一行单独铺横的要求枚举集合中出现连续 ...
- POJ2411 Mondriaan's Dream 【状压dp】
没错,这道题又是我从LZL里的博客里剽过来的,他的题真不错,真香. 题目链接:http://poj.org/problem?id=2411 题目大意:给一个n * m的矩形, 要求用 1 * 2的小方 ...
- poj2411 Mondriaan's Dream【状压DP】
Mondriaan's Dream Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 20822 Accepted: 117 ...
- poj2411 Mondriaan's Dream (状压dp+多米诺骨牌问题)
这道题的解析这个博客写得很好 https://blog.csdn.net/shiwei408/article/details/8821853 大致意思就是我们可以只处理两行之间的关系,然后通过这两个关 ...
- 「状压DP」「暴力搜索」排列perm
「状压DP」「暴力搜索」排列 题目描述: 题目描述 给一个数字串 s 和正整数 d, 统计 sss 有多少种不同的排列能被 d 整除(可以有前导 0).例如 123434 有 90 种排列能被 2 整 ...
- 「BZOJ 5010」「FJOI 2017」矩阵填数「状压DP」
题意 你有一个\(h\times w\)的棋盘,你需要在每个格子里填\([1, m]\)中的某个整数,且满足\(n\)个矩形限制:矩形的最大值为某定值.求方案数\(\bmod 10^9+7\) \(h ...
- POJ 题目2411 Mondriaan's Dream(状压DP)
Mondriaan's Dream Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 13519 Accepted: 787 ...
- POJ 2411 Mondriaan's Dream 【状压Dp】 By cellur925
题目传送门 这道题暑假做的时候太模糊了,以前的那篇题解大家就别看了==.今天再复习状压感觉自己当时在写些什么鸭.... 题目大意:给你一个\(n\)*\(m\)的棋盘和许多\(1*2\)的骨牌,骨牌可 ...
随机推荐
- 跨语言调用Hangfire定时作业服务
跨语言调用Hangfire定时作业服务 背景 Hangfire允许您以非常简单但可靠的方式执行后台定时任务的工作.内置对任务的可视化操作.非常方便. 但令人遗憾的是普遍都是业务代码和hagnfire服 ...
- sql 表值函数与标量值函数
写sql存储过程经常需要调用一些函数来使处理过程更加合理,也可以使函数复用性更强,不过在写sql函数的时候可能会发现,有些函数是在表值函数下写的有些是在标量值下写的,区别是表值函数只能返回一个表,标量 ...
- jupyter使用
jupyter使用 安装 在anaconda3的安装路径中,尽量避免使用汉字或者括号. 启动 在Windows上正确安装Anaconda3,确认配置好环境变量,然后再命令行中输入jupyter not ...
- vue组件内部引入远程js文件
之所以要做这个是因为,在一个组件内部需要引入一个js文件来定位.如果放在index.html,这样每个组件都会有这个js.所以需要在组件内单独引入. 第一种操作 Dom引入js: export def ...
- toTree
// js实现树级递归, // 通过js生成tree树形菜单(递归算法) const data = [ { id: 1, name: "办公管理", pid: 0 }, { id: ...
- tomcat启动的时候报错Failed to start component
在idea中运行tomcat时,遇到异常,异常信息如下: 16-Jan-2018 16:33:37.325 信息 [localhost-startStop-1] org.apache.catalina ...
- 20181114教学sql
--精确查找:查询水表编号为30408的业主记录 ' --模糊查询:查询业主名称包含'刘'的业主记录 SELECT * FROM T_OWNERS WHERE NAME LIKE '%刘%' --AN ...
- AngularJS基于模块化的MVC实现
AngularJS基于模块化的MVC实现 <!DOCTYPE html> <html> <head> <meta charset="UTF-8&qu ...
- checkout 多选 全选(亲测有效)
<input type="button" id="btn1" value="全选"> <input type=" ...
- linux audit (9)--生成audit报表
aureport这个命令可以生成一个总结性的柱状图报表,默认情况下,在/var/log/audit目录下的所有日志文件都会生成一个报表,也可以使用如下命令来指定一个不同的文件,aureport opt ...