没错,这道题又是我从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】的更多相关文章

  1. [poj2411] Mondriaan's Dream (状压DP)

    状压DP Description Squares and rectangles fascinated the famous Dutch painter Piet Mondriaan. One nigh ...

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

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

  3. Poj 2411 Mondriaan's Dream(状压DP)

    Mondriaan's Dream Time Limit: 3000MS Memory Limit: 65536K Description Squares and rectangles fascina ...

  4. POJ 2411 Mondriaan's Dream ——状压DP 插头DP

    [题目分析] 用1*2的牌铺满n*m的格子. 刚开始用到动规想写一个n*m*2^m,写了半天才知道会有重复的情况. So Sad. 然后想到数据范围这么小,爆搜好了.于是把每一种状态对应的转移都搜了出 ...

  5. $POJ2411\ Mondriaan's\ Dream$ 状压+轮廓线$dp$

    传送门 Sol 首先状压大概是很容易想到的 一般的做法大概就是枚举每种状态然后判断转移 但是这里其实可以轮廓线dp 也就是从上到下,从左到右地放方块 假设我们现在已经放到了$(i,j)$这个位置 那么 ...

  6. 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\)时, ...

  7. poj2411 Mondriaan's Dream (轮廓线dp、状压dp)

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

  8. POJ 2411 Mondriaan'sDream(状压DP)

    题目大意:一个矩阵,只能放1*2的木块,问将这个矩阵完全覆盖的不同放法有多少种. 解析:如果是横着的就定义11,如果竖着的定义为竖着的01,这样按行dp只需要考虑两件事儿,当前行&上一行,是不 ...

  9. POJ2411 - Mondriaan's Dream(状态压缩DP)

    题目大意 给定一个N*M大小的地板,要求你用1*2大小的砖块把地板铺满,问你有多少种方案? 题解 刚开始时看的是挑战程序设计竞赛上的关于铺砖块问题的讲解,研究一两天楞是没明白它代码是怎么写的,智商捉急 ...

  10. POJ2411 Mondriaan's Dream 题解 轮廓线DP

    题目链接:http://poj.org/problem?id=2411 题目大意 给你一个 \(n \times m (1 \le n,m \le 11)\) 的矩阵,你需要用若干 \(1 \time ...

随机推荐

  1. Mac OS 系统开发环境的一些坑

    最近换 Mac OS 系统开发,运行项目时遇到各种报错,记录下: 1.拉取项目后,需要安装依赖 npm install ,提示需要安装 xcode,报错如下. 从官网下载 xcode 时提示要更新最新 ...

  2. 使用ImageProcessor、CodeCarvings.Piczard组件生成缩略图和添加水印

    技术栈: 1.ImageProcessor(专业图像处理,不能合成水印,NetCore中有它的升级版ImageSharp目前是预览包) 2.CodeCarvings.Piczard(缩略图,水印都能搞 ...

  3. C语言中的指针加减偏移量

    C语言指针偏移技巧(也是一个要注意的坑) - 陈杰柱的博客 - CSDN博客  https://blog.csdn.net/cjzjolly/article/details/82116772 C语言中 ...

  4. 2016 Multi-University Training Contest 1 部分题解

    第一场多校,出了一题,,没有挂零还算欣慰. 1001,求最小生成树和,确定了最小生成树后任意两点间的距离的最小数学期望.当时就有点矛盾,为什么是求最小的数学期望以及为什么题目给了每条边都不相等的条件. ...

  5. mysql 1045 - Access denied for user 'root'@'*.*.*.*' (using password YES)

    远程无法连接mysql 解决方法: 1.在服务器登录数据 mysql -uroot -hlocalhost -P3306 -p Enter password: Welcome to the MySQL ...

  6. FFmpeg之av_register_all()

    1. av_register_all() 该函数位于 libavformat/allformats.c 中. 该函数主要是注册所有的编解码器.复用/解复用组件等. /* * Initialize li ...

  7. arcgis python RefreshActiveView CLEAR_SELECTION

    import arcpy mxd = arcpy.mapping.MapDocument("CURRENT") df = arcpy.mapping.ListDataFrames( ...

  8. ArcGIS中国工具3.0正式发布

    ArcGIS中国工具3.0正式发布,新功能有 1.  支持面积分割(见4.6),见https://weibo.com/tv/v/HsM2ksYY3?fid=1034:4368578107884427 ...

  9. Access denied for user 'root'@'localhost'问题的解决

    mysql> grant all privileges on *.* to root@'localhost' identified by '密码'; mysql> flush privil ...

  10. 封装带SSH跳板机的MYSQL

    一.封装带SSH跳板机的MYSQL 二.配置settting import pymysql from sshtunnel import SSHTunnelForwarder class MyDb(ob ...