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 ...
随机推荐
- SD协议-状态机
1.SD卡状态回顾 2.SD卡数据传输模式 SD卡在接收到CMD3之后就会进入data transfer state,初始状态时standby state,表示空闲状态 SD卡在standby sta ...
- uniapp 子页面 滚动监听 是否到底
主要属性: handleScrollToLower <template> <view class="menu"> <scroll-view id=& ...
- android应用申请加入电池优化白名单
首先,在 AndroidManifest.xml 文件中配置一下权限: 1 <uses-permission android:name="android.permission.REQU ...
- Grafana监控Oracle数据库的表大小等信息
Grafana监控Oracle数据库的表大小等信息 方案 oracledb_exporter 以及 prometheus grafana 使用的SQL以及配置文件 [[metric]] context ...
- [转帖]深入了解 gRPC:协议
https://cn.pingcap.com/blog/grpc 经过很长一段时间的开发,TiDB 终于发了 RC3.RC3 版本对于 TiKV 来说最重要的功能就是支持了 gRPC,也就意味着后面大 ...
- [转帖]为什么不推荐使用/etc/fstab
https://www.jianshu.com/p/af49a5d0553f 对于工作中使用服务器的公司来讲,每到节假日来临时,总免不了对服务器进行下电.而收假回来的早上,则会有一个早上的时间会花费在 ...
- [转帖]【rpm】源码包制作rpm包|修改rpm、重新制作rpm包
目录 前言 安装rpmbuild rpmbuild制作rpm 包 同时生成devel包 阻止rpmbuid打包时strip程序/库 修改rpm.重新制作rpm包 RPM 打包 工具 SPEC文件 sp ...
- Python学习之七_input和print
Python学习之七_input和print 摘要 python3 之后 函数必须带 () 了 因为我开始学习的比较晚, 所以准备Python3开始学起 前面主要是模仿别人的代码进行学习 后续慢慢学习 ...
- [转帖]CPU的制造和概念
https://plantegg.github.io/2021/06/01/CPU%E7%9A%84%E5%88%B6%E9%80%A0%E5%92%8C%E6%A6%82%E5%BF%B5/ 为了让 ...
- Redis 菜鸟进阶
Redis 菜鸟进阶 背景 最近产品一直要优化性能,加强高可用. 有一个课题是Redis高可用与性能调优. 我这边其实获取到的内容很有限. 最近济南疫情严重,自己锁骨骨折. 然后通勤时间基本上都用来查 ...