题目链接

题目

题目描述

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 则不合法,否则有转移方程:

\[dp[i][j] = \sum dp[i-1][k]
\]

时间复杂度 \(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的更多相关文章

  1. POJ 题目2411 Mondriaan's Dream(状压DP)

    Mondriaan's Dream Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 13519   Accepted: 787 ...

  2. HDU 1400 (POJ 2411 ZOJ 1100)Mondriaan's Dream(DP + 状态压缩)

    Mondriaan's Dream Problem Description Squares and rectangles fascinated the famous Dutch painter Pie ...

  3. POJ2411 Mondriaan's Dream(状态压缩)

    Mondriaan's Dream Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 15295   Accepted: 882 ...

  4. POJ 2411 Mondriaan's Dream -- 状压DP

    题目:Mondriaan's Dream 链接:http://poj.org/problem?id=2411 题意:用 1*2 的瓷砖去填 n*m 的地板,问有多少种填法. 思路: 很久很久以前便做过 ...

  5. POJ2411 铺地砖 Mondriaan's Dream

    Mondriaan's Dream Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 15962   Accepted: 923 ...

  6. [poj P2411] Mondriaan's Dream

    [poj P2411] Mondriaan's Dream Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 18023   A ...

  7. POJ 2411 Mondriaan's Dream 插头dp

    题目链接: http://poj.org/problem?id=2411 Mondriaan's Dream Time Limit: 3000MSMemory Limit: 65536K 问题描述 S ...

  8. 【POJ2411】Mondriaan's Dream(轮廓线DP)

    [POJ2411]Mondriaan's Dream(轮廓线DP) 题面 Vjudge 题解 这题我会大力状压!!! 时间复杂度大概是\(O(2^{2n}n^2)\),设\(f[i][S]\)表示当前 ...

  9. poj2411 Mondriaan's Dream【状压DP】

    Mondriaan's Dream Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 20822   Accepted: 117 ...

  10. POJ - 2411 Mondriaan's Dream(轮廓线dp)

    Mondriaan's Dream Squares and rectangles fascinated the famous Dutch painter Piet Mondriaan. One nig ...

随机推荐

  1. 如何使用Oracle Enterprise Manager Database Express连接到PDB数据库

    1.问题 1.1重复弹出登录框,无法登陆 关闭登录框,显示invalid container name 1.2 重启后PDB数据库处于mounted挂载状态,未打开导致使用 Enterprise 登陆 ...

  2. 【MMC子系统】 二、EMMC协议

    [MMC子系统] 二.EMMC协议 1.前言 在上一节,我们知道EMMC.SD.SDIO三种规范都是在MMC规范之上发展而来,协议相差不大,所以Linux Kernel才能使用MMC子系统来统一管理! ...

  3. 【Git】如何在github上提交PR(Pull Request)

    [来源]https://mp.weixin.qq.com/s/yHQRjpVeZVV4PuoUKM0FSw

  4. 左值,右值,引用,指针,常量,auto如何组合?

    左值,右值,引用,指针,常量,auto如何组合? 左值引用:int &a = b; 左值引用是通过使用&符号来声明的,例如int &a. 左值引用用于绑定到左值(可标识的.持久 ...

  5. 使用Python+FFMPEG实现视频分割与合并

    前言 日常中偶尔会遇到需要简单剪辑处理视频的场景,以前我可能会拿出PR来剪辑一下,(别跟我说国产那些软件,剪辑完视频强制加上广告片头片尾恶心的一批),但是PR毕竟太重量级,剪个简单的视频都要花不少时间 ...

  6. [转帖]Kafka故障之磁盘打满

    https://www.jianshu.com/p/095e820361ae 问:磁盘打满扩容后能正常重启吗?答:不一定 要看文件格式是否损坏(log.index等).如果损坏会报错:index fi ...

  7. [转帖]sendfile“零拷贝”、mmap内存映射、DMA

    https://www.jianshu.com/p/7863667d5fa7 KAFKA推送消息用到了sendfile,落盘技术用到了mmap,DMA贯穿其中. 先说说零拷贝 零拷贝并不是不需要拷贝, ...

  8. [转帖]从CPU指令集自主到信息技术产业自主

    https://zhuanlan.zhihu.com/p/365210753 现代信息技术的应用都是以计算机为基础,CPU是计算机中的信息处理中枢.CPU指令集是CPU逻辑电路与操作系统和应用程序交流 ...

  9. 截止2021年linux发行版

  10. SAP Gateway Trace

    最近在SAP PE项目上遇到一个需求要求记录所有的ODATA(含S4/CLOUD API)的报文. Below T-codes recording logging and tracing: /IWFN ...