POJ2411 Mondriaan's Dream 【状压dp】
没错,这道题又是我从LZL里的博客里剽过来的,他的题真不错,真香。
题目链接:http://poj.org/problem?id=2411
题目大意:给一个n * m的矩形, 要求用 1 * 2的小方块去填充满这个矩形, 有多少种填充方式。(1<=n, m <= 11)
思路:
1.凭借做题的经验,能想到这道题一定是无法用暴力去解决,因为方法数肯定很多,暴力跑不出来。
2.看到这题我想到的是用状态转移,因为大的矩形填充可以由多个小的矩形填充来组成,这是最开始的想法,但是这种想法远远不够。
3.用到状压dp,这篇博客讲解的非常清楚:https://blog.csdn.net/u014634338/article/details/50015825
4.总的来说就是先预处理出第一行的所有状态,然后dp从第2行开始,check()本行与前一行的状态是否兼容,然后把相应状态的方法数叠加上来。
5.0代表竖放,竖放的第二个砖块为1. 1代表横放,所占的两个位置都为1
代码里写了很详细的注释:
#include<stdio.h>
#include<string.h>
#include<algorithm>
#define mem(a, b) memset(a, b, sizeof(a))
using namespace std; int row, col;
long long dp[][ << ]; //代表前 i 行,第i行状态为j时的方案数目.因此答案所求的是 dp[row][(1 << m) - 1] int ok(int state)
{
for(int j = ; j < col; ) //枚举每一列的状态 前j列已经被确定
{
if(state & ( << j)) //第 j 列为 1
{
if(j == col - ) //列数不够
return ;
if(state & ( << (j + ))) //第 j + 1列为 1, 横放
j += ;
else//第 j + 1 列为 0, 在第 j 列还未被确定的情况下是不合法的
return ;
}
else//第 j 列为 0, 竖放
{
j += ;
}
}
return ;
} int check(int now, int pre)
{
for(int j = ; j < col; )//枚举每一列判断是否与前一行有冲突
{
if(now & ( << j))//第i行第j列为1
{
if(pre & ( << j))//第i-1行第j列也为1,那么第i行必然是横放
{
if(j == col - )
return ;
if(!(now & ( << (j + ))) || !(pre & ( << (j + ))))
//第i行和第i-1行的第j+1都必须是1,否则是非法的
return ;
j += ;
}
else //第i-1行第j列为0,说明第i行第j列是竖放
j += ;
}
else //第i行第j列为0,那么第i-1行的第j列应该是已经填充了的
{
if(pre & ( << j))
j += ;
else
return ;
}
}
return ;
} int main()
{
while(scanf("%d%d", &row, &col) != EOF)
{
if(row == && col == )
break;
if(col > row) //将图较小边作为宽,这样一行中的状态数较少,可以提高效率
swap(col, row);
if((row * col) % ) //若面积为 奇数 , 则不可能存在覆盖满的情况
{
printf("0\n");
continue;
}
mem(dp, );
int tot = << col;
for(int i = ; i < tot; i ++) //枚举第1行的所有状态,初始化第1行的方案数
{
if(ok(i))
dp[][i] = ;
}
for(int i = ; i <= row; i ++) //dp从第2行开始,因为第1行已经预处理了
{
for(int j = ; j < tot; j ++)//第 i 行的状态
{
for(int k = ; k < tot; k ++)//第 i - 1行的状态
{
if(check(j, k))
dp[i][j] += dp[i - ][k];
}
}
}
printf("%lld\n", dp[row][( << col) - ]);
}
return ;
}
POJ2411 Mondriaan's Dream 【状压dp】的更多相关文章
- [poj2411] Mondriaan's Dream (状压DP)
状压DP Description Squares and rectangles fascinated the famous Dutch painter Piet Mondriaan. One nigh ...
- 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)
Mondriaan's Dream Time Limit: 3000MS Memory Limit: 65536K Description Squares and rectangles fascina ...
- POJ 2411 Mondriaan's Dream ——状压DP 插头DP
[题目分析] 用1*2的牌铺满n*m的格子. 刚开始用到动规想写一个n*m*2^m,写了半天才知道会有重复的情况. So Sad. 然后想到数据范围这么小,爆搜好了.于是把每一种状态对应的转移都搜了出 ...
- $POJ2411\ Mondriaan's\ Dream$ 状压+轮廓线$dp$
传送门 Sol 首先状压大概是很容易想到的 一般的做法大概就是枚举每种状态然后判断转移 但是这里其实可以轮廓线dp 也就是从上到下,从左到右地放方块 假设我们现在已经放到了$(i,j)$这个位置 那么 ...
- POJ-2411 Mondriann's Dream (状压DP)
求把\(N*M(1\le N,M \le 11)\) 的棋盘分割成若干个\(1\times 2\) 的长方形,有多少种方案.例如当 \(N=2,M=4\)时,共有5种方案.当\(N=2,M=3\)时, ...
- poj2411 Mondriaan's Dream (轮廓线dp、状压dp)
Mondriaan's Dream Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 17203 Accepted: 991 ...
- POJ 2411 Mondriaan'sDream(状压DP)
题目大意:一个矩阵,只能放1*2的木块,问将这个矩阵完全覆盖的不同放法有多少种. 解析:如果是横着的就定义11,如果竖着的定义为竖着的01,这样按行dp只需要考虑两件事儿,当前行&上一行,是不 ...
- POJ2411 - Mondriaan's Dream(状态压缩DP)
题目大意 给定一个N*M大小的地板,要求你用1*2大小的砖块把地板铺满,问你有多少种方案? 题解 刚开始时看的是挑战程序设计竞赛上的关于铺砖块问题的讲解,研究一两天楞是没明白它代码是怎么写的,智商捉急 ...
- POJ2411 Mondriaan's Dream 题解 轮廓线DP
题目链接:http://poj.org/problem?id=2411 题目大意 给你一个 \(n \times m (1 \le n,m \le 11)\) 的矩阵,你需要用若干 \(1 \time ...
随机推荐
- 【转】css样式的书写顺序及原理——很重要!
记得刚开始学习前端的时候,每次写css样式都是用到什么就在样式表后添加什么,完全没有考虑到样式属性的书写顺序对网页加载代码的影响.后来逐渐才知道正确的样式顺序不仅易于查看,并且也属于css样式优化的一 ...
- eq(index|-index)
eq(index|-index) 概述 获取当前链式操作中第N个jQuery对象,返回jQuery对象,当参数大于等于0时为正向选取,比如0代表第一个,1代表第二个.当参数为负数时为反向选取,比如-1 ...
- B/S架构大文件上传问题
核心原理: 该项目核心就是文件分块上传.前后端要高度配合,需要双方约定好一些数据,才能完成大文件分块,我们在项目中要重点解决的以下问题. * 如何分片: * 如何合成一个文件: * 中断了从哪个分片开 ...
- IntelliJ 如何显示代码的代码 docs
希望能够在 IntelliJ 代码上面显示方法的 docs. 如何进行显示? 你可以使用 Ctrl + Q 这个快捷键来查看方法的 Docs. https://blog.ossez.com/archi ...
- JS学习-01
01
- node中从express到koa再到koa2的发展历程
koa是Express的下一代基于Node.js的web框架,目前有1.x和2.0两个版本. 历史 1. Express Express是第一代最流行的web框架,它对Node.js的http进行了封 ...
- Django基础之CBV和FBV
我们之前写过的是基于函数的view,就叫FBV.还可以把view写成基于类的. 1. FBV版 def add_class(request): if request.method == "P ...
- HTML/HTML5 知识点思维导图
1 - 浏览器 | 浏览器页面构成 2 - 浏览器 | 浏览器内核相关知识点 3 - W3C | 对WEB标准以及W3C的理解与认识? 4 - 标签 | Doctype相关知识点 5 - 标签 | m ...
- [CTS2019]珍珠——二项式反演
[CTS2019]珍珠 考虑实际上,统计多少种染色方案,使得出现次数为奇数的颜色数<=n-2*m 其实看起来很像生成函数了 n很大?感觉生成函数会比较整齐,考虑生成函数能否把n放到数值的位置,而 ...
- spring boot打包以及centos下部署
spring boot打包以及部署 一.打包 springboot的打包方式有很多种.有打成war的,有打成jar的,也有直接提交到github,通过jekins进行打包部署的.这里主要介绍如何打成j ...