NC51189 Mondriaan's Dream
题目
题目描述
Squares and rectangles fascinated the famous Dutch painter Piet Mondriaan. One night, after producing the drawings in his 'toilet series' (where he had to use his toilet paper to draw on, for all of his paper was filled with squares and rectangles), he dreamt of filling a large rectangle with small rectangles of width 2 and height 1 in varying ways.

Expert as he was in this material, he saw at a glance that he'll need a computer to calculate the number of ways to fill the large rectangle whose dimensions were integer values, as well. Help him, so that his dream won't turn into a nightmare!
输入描述
The input contains several test cases. Each test case is made up of two integer numbers: the height h and the width w of the large rectangle. Input is terminated by h=w=0. Otherwise, 1≤h,w≤111\leq h,w\leq 111≤h,w≤11.
输出描述
For each test case, output the number of different ways the given rectangle can be filled with small rectangles of size 2 times 1. Assume the given large rectangle is oriented, i.e. count symmetrical tilings multiple times.
示例1
输入
1 2
1 3
1 4
2 2
2 3
2 4
2 11
4 11
0 0
输出
1
0
1
2
3
5
144
51205
题解
知识点:状压dp。
一道经典的状压dp,状态设置十分巧妙。考虑一行一行摆,因为要摆满且有两种块,单纯用 \(01\) 表示横着摆竖着摆会出问题,竖着的会影响下一行,横着的要连着放,非常麻烦。考虑设 \(dp[i][st]\) 表示考虑第 \(i\) 行, 且状态是 \(st\) ,其中 \(1\) 代表这格会延长至下一行,\(0\) 代表这格不会延长至下一行。这样,如果上一行状态是 \(st1\) ,这一行状态是 \(st2\) ,\(st1 | st2\) 中 \(1\) 表示这一行哪些格子被竖着的块占据了,两行的 \(1\) 都对应一个竖块,剩下的 \(0\) 则是横的,于是统计连续出现的 \(0\) 是否为奇数,如果是则状态组合 \(st1 | st2\) 不可能发生。
先预处理出状态组合 \(st1|st2\) 是否可能发生,共 \(2^m\) 种可能,记录在 \(vis\) 数组。
接下来枚举行,本层状态和上层状态,满足 j & k || !vis[j | k] == 1 则不合法,否则有转移方程:
\]
时间复杂度 \(O(n \cdot 4^m)\)
空间复杂度 \(O(n \cdot 2^m)\)
代码
#include <bits/stdc++.h>
#define ll long long
using namespace std;
ll dp[12][1 << 11];///第 i 行,状态 j,0表示横着放中的一格或者上上层竖着放下来的(即没有往下延伸),1表示竖着放(往下延伸了)
bool vis[1 << 11];
int main() {
std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int n, m;
while (cin >> n >> m, n || m) {
for (int i = 0;i < (1 << m);i++) {///这里的状态不一样,1 表示单独存在的,0 表示是连续两个的
vis[i] = 1;
bool ok = 1;
for (int j = 1;j <= m;j++) {
if (((i >> (j - 1)) & 1)) vis[i] &= ok, ok = 1;
else ok ^= 1;
}
vis[i] &= ok;///最后没有1的残留状态转移
}
memset(dp, 0, sizeof(dp));
dp[0][0] = 1;
for (int i = 1;i <= n;i++) {
for (int j = 0;j < (1 << m);j++) {///本层
for (int k = 0;k < (1 << m);k++) {///上层
if (j & k || !vis[j | k]) continue;
///第一个判断1是否重叠,因为上面1,下面不能放1
///第二个判断,把上面戳下来的一起当作1表示独立一格,记录连在一起的0的个数是否是偶数
dp[i][j] += dp[i - 1][k];
}
}
}
cout << dp[n][0] << '\n';///最终一定是全0,不会往下戳的情况
}
return 0;
}
NC51189 Mondriaan's Dream的更多相关文章
- POJ 题目2411 Mondriaan's Dream(状压DP)
Mondriaan's Dream Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 13519 Accepted: 787 ...
- HDU 1400 (POJ 2411 ZOJ 1100)Mondriaan's Dream(DP + 状态压缩)
Mondriaan's Dream Problem Description Squares and rectangles fascinated the famous Dutch painter Pie ...
- POJ2411 Mondriaan's Dream(状态压缩)
Mondriaan's Dream Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 15295 Accepted: 882 ...
- POJ 2411 Mondriaan's Dream -- 状压DP
题目:Mondriaan's Dream 链接:http://poj.org/problem?id=2411 题意:用 1*2 的瓷砖去填 n*m 的地板,问有多少种填法. 思路: 很久很久以前便做过 ...
- POJ2411 铺地砖 Mondriaan's Dream
Mondriaan's Dream Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 15962 Accepted: 923 ...
- [poj P2411] Mondriaan's Dream
[poj P2411] Mondriaan's Dream Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 18023 A ...
- POJ 2411 Mondriaan's Dream 插头dp
题目链接: http://poj.org/problem?id=2411 Mondriaan's Dream Time Limit: 3000MSMemory Limit: 65536K 问题描述 S ...
- 【POJ2411】Mondriaan's Dream(轮廓线DP)
[POJ2411]Mondriaan's Dream(轮廓线DP) 题面 Vjudge 题解 这题我会大力状压!!! 时间复杂度大概是\(O(2^{2n}n^2)\),设\(f[i][S]\)表示当前 ...
- poj2411 Mondriaan's Dream【状压DP】
Mondriaan's Dream Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 20822 Accepted: 117 ...
- POJ - 2411 Mondriaan's Dream(轮廓线dp)
Mondriaan's Dream Squares and rectangles fascinated the famous Dutch painter Piet Mondriaan. One nig ...
随机推荐
- DBA实战面试题(一)
数据库面试测试题(一) 简述当前主流RDBMS软件有哪些?开源且跨平台的数据库软件有哪些? 参考答案 当前主流的数据库服务器软件有: Oracle . DB2 . SQL SERVER .MySQL ...
- asp.net core之实时应用
本文将介绍ASP.NET Core SignalR,这是一个强大的实时通信库,用于构建实时.双向通信应用程序.我们将探讨SignalR的基本概念.架构和工作原理,并提供一些示例代码来帮助读者更好地理解 ...
- PG数据库存储验证
PG数据库存储验证 背景 最近学习了SQLServer数据库的varchar和nvarchar的存储 想到PG数据库其实没让选择字符集,也没有nvarchar 所以想学习一下nvarchar的使用情况 ...
- [转帖][MySQL 8.2.0] 从参数变化解读 MySQL 8.2.0 发版说明
https://www.mryunwei.com/482476.html 日前,MySQL 8.2.0 创新版本已正式上线,并提供安装包下载,但 docker 镜像尚未更新. 在 MySQL 8.1. ...
- [转帖]Shell编程之正则表达式与文本处理器(grep、sort、uniq、tr、cut)
目录 正则表达式概念 正则表达式的作用 元字符 grep命令在文本中查找指定的字符串 sort命令排序 uniq命令快捷去重 tr命令替换.压缩和删除 cut命令快速裁剪命令 expr substr ...
- [转帖]Linux运维常用150个命令
Linux运维常用150个命令 转载自:www.cnblogs.com/bananaaa/p/7774467.html 命令 功能说明 线上查询及帮助命令(2个) man 查看命令帮助,命令的词典,更 ...
- [转帖]springboot中使用skywalking实现日志追踪
文章目录 SkyWalking分布式追踪系统 介绍 主要架构 环境 引入依赖 配置Log4j2 下载编译好的8.7.0版本包 使用探针实现日志追踪 启动脚本 启动Java服务 访问服务 使用UI 切换 ...
- 自己想的一些判断存储长度的sql
create table zhaobsh (t1 date ,t2 TIMESTAMP) insert into zhaobsh values (CURRENT_DATE,CURRENT_TIMEST ...
- date的命令使用.
date命令的使用 1.直接用date命令显示日期时间 在命令行中输入date然后回车,显示结果"Wed Aug 7 08:58:07 CST 2019".这是系统根据设定的时区显 ...
- 【转载】基于Tablestore Timeline的IM(即时通讯)消息系统架构 - 架构篇
本文原作者:木洛,阿里云高级技术专家,内容有优化和修订,感谢原作者.原文链接:https://developer.aliyun.com/article/698301 IM全称是『Instant Mes ...