poj 2411 Mondriaan's Dream 骨牌铺放 状压dp
题目链接
题意
用\(1\times 2\)的骨牌铺满\(H\times W(H,W\leq 11)\)的网格,问方案数。
思路
参考focus_best.
竖着的骨牌用\(\begin{pmatrix}0\\1\end{pmatrix}\)表示,横着的骨牌用\(\begin{pmatrix}1&1\end{pmatrix}\)表示。
则对于第\(i\)行,与之相容的第\(i-1\)行的状态需满足:
- 第\(i\)行是0的位置,第\(i-1\)行必须是1;
- 第\(i\)行是1的位置,第\(i-1\)行可为1可为0;如果是1则需满足,这样的连续的1的个数必为偶数(因为为横放)。
此外,
最后一行必为全1状态,
第一行需满足可以作为第一行的条件:这等价于,第一行的上一行可以表示为全1状态。
Code
#include <cstdio>
#include <cstring>
#include <iostream>
#define F(i, a, b) for (int i = (a); i < (b); ++i)
#define F2(i, a, b) for (int i = (a); i <= (b); ++i)
#define dF(i, a, b) for (int i = (a); i > (b); --i)
#define dF2(i, a, b) for (int i = (a); i >= (b); --i)
#define maxn 13
#define maxs 2100
using namespace std;
typedef long long LL;
int h, w; LL dp[maxs][maxn];
bool vis[maxs][maxn], hori[maxn];
bool check(int s1, int s2) {
memset(hori, 0, sizeof hori);
F(i, 0, w) {
if (!(s2&(1<<i))) {
if (!(s1&(1<<i))) return false;
}
else {
if (s1&(1<<i)) hori[i] = true;
}
}
int cont = 0; bool flag = false;
F(i, 0, w+1) {
if (!hori[i]) {
if (cont&1) return false;
cont = 0;
}
else ++cont;
}
return true;
}
LL dfs(int state, int row) {
if (!row) {
if (state==(1<<w)-1) return 1;
else return 0;
}
if (vis[state][row]) return dp[state][row];
vis[state][row] = true;
LL temp=0;
F(i, 0, 1<<w) {
if (check(i, state)) temp += dfs(i, row-1);
}
return dp[state][row] = temp;
}
void work() {
memset(vis, 0, sizeof vis);
memset(dp, 0, sizeof dp);
if (h<w) swap(h,w);
printf("%lld\n", dfs((1<<w)-1, h));
}
int main() {
while (scanf("%d%d", &h, &w) != EOF && h && w) work();
return 0;
}
poj 2411 Mondriaan's Dream 骨牌铺放 状压dp的更多相关文章
- POJ 2411 Mondriaan's Dream 插头dp
题目链接: http://poj.org/problem?id=2411 Mondriaan's Dream Time Limit: 3000MSMemory Limit: 65536K 问题描述 S ...
- POJ 2411 Mondriaan's Dream -- 状压DP
题目:Mondriaan's Dream 链接:http://poj.org/problem?id=2411 题意:用 1*2 的瓷砖去填 n*m 的地板,问有多少种填法. 思路: 很久很久以前便做过 ...
- POJ 2411 Mondriaan's Dream ——状压DP 插头DP
[题目分析] 用1*2的牌铺满n*m的格子. 刚开始用到动规想写一个n*m*2^m,写了半天才知道会有重复的情况. So Sad. 然后想到数据范围这么小,爆搜好了.于是把每一种状态对应的转移都搜了出 ...
- Poj 2411 Mondriaan's Dream(状压DP)
Mondriaan's Dream Time Limit: 3000MS Memory Limit: 65536K Description Squares and rectangles fascina ...
- [POJ] 2411 Mondriaan's Dream
Mondriaan's Dream Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 18903 Accepted: 10779 D ...
- 多米诺骨牌放置问题(状压DP)
例题: 最近小A遇到了一个很有趣的问题: 现在有一个\(n\times m\)规格的桌面,我们希望用\(1 \times 2\)规格的多米诺骨牌将其覆盖. 例如,对于一个\(10 \times 11\ ...
- POJ 1038 Bugs Integrated Inc (复杂的状压DP)
$ POJ~1038~~\times Bugs~Integrated~Inc: $ (复杂的状压DP) $ solution: $ 很纠结的一道题目,写了大半天,就想练练手,结果这手生的.其实根据之前 ...
- Poj 2411 Mondriaan's Dream(压缩矩阵DP)
一.Description Squares and rectangles fascinated the famous Dutch painter Piet Mondriaan. One night, ...
- POJ - 2411 Mondriaan's Dream(轮廓线dp)
Mondriaan's Dream Squares and rectangles fascinated the famous Dutch painter Piet Mondriaan. One nig ...
随机推荐
- 老男孩Python全栈第2期+课件笔记【高清完整92天整套视频教程】
点击了解更多Python课程>>> 老男孩Python全栈第2期+课件笔记[高清完整92天整套视频教程] 课程目录 ├─day01-python 全栈开发-基础篇 │ 01 pyth ...
- JAVA解析XML有哪几种方法?并简述各自的优缺点
DOM: 是用与平台和语言无关的方式表示XML文档的官方W3C标准,分析该结构通常需要加载整个文档和构造层次结构,然后才能做任何工作.是基于信息层次的 优点有:由于树在内存中是持久的,因此可以修改它以 ...
- Python基础:条件与循环
条件语句 除了 boolean 类型的数据,条件判断最好是显性的 if i != 0: ... 而不是只写出变量名: if i: ... For循环与While循环 通常来说,如果你只是遍历一个已知的 ...
- RGB色彩的计算机表示
计算机显示模式[编辑] 24比特模式[编辑] 每像素24位(比特s per pixel,bpp)编码的RGB值:使用三个8位无符号整数(0到255)表示红色.绿色和蓝色的强度.这是当前主流的标准表示方 ...
- UVA - 753 A Plug for UNIX(网络流)
题意 给定一些插头设备和插座,有一些方法可以把其中一些插头变成另一种插头.求无法匹配插座的插头设备个数. 题解 用\(map\)给每个字符串标号为\(a_i\)和\(b_i\). 读入每种改变插头的方 ...
- imageX
imageX 编辑 ImageX 是一个命令行工具,原始设备制造商 (OEM) 和公司可以使用它来捕获.修改和应用基于文件的磁盘映像以进行快速部署.ImageX 可以使用 Windows 映像 (.w ...
- IOS开发---菜鸟学习之路--(十六)-将Image转换为Base64
我们直接在.m文件的引用头文件部分 和 @interface AddPictureViewController () 之间 加入 增加部分的代码 然后就可以使用图片转Base64了 #impor ...
- leetcode 【 Best Time to Buy and Sell Stock 】python 实现
思路: Say you have an array for which the ith element is the price of a given stock on day i. If you w ...
- python矩阵和向量的转置问题
numpy有很多方法进行转置,这里由于时间和精力限制(主要是我实在比较懒,有一个基本上一直能使的,就懒得看其他的了),其他方法我没研究,这里我总结的东西,如果有问题,欢迎各路大佬拍砖 一.创建矩阵: ...
- Leetcode 629.K个逆序对数组
K个逆序对数组 给出两个整数 n 和 k,找出所有包含从 1 到 n 的数字,且恰好拥有 k 个逆序对的不同的数组的个数. 逆序对的定义如下:对于数组的第i个和第 j个元素,如果满i < j且 ...