没错,这道题又是我从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. 【Android-连接数据库】 直接连接SqlServer数据库

    一.测试过的开发环境 Eclispse + SqlServer2008R2 二.下载支持Android的SQL驱动 只能下载1.2.7版本的,将 jtds-1.2.7.jar 包放在android项目 ...

  2. 多线程中volatile关键字的作用

    原文链接:https://blog.csdn.net/xuwentao37x/article/details/27804169 多线程的程序是出了名的难编写.难验证.难调试.难维护,这通常是件苦差事. ...

  3. 【线性代数】2-1:解方程组(Ax=b)

    title: [线性代数]2-1:解方程组(Ax=b) toc: true categories: Mathematic Linear Algebra date: 2017-08-31 15:08:3 ...

  4. NotFoundError (see above for traceback): Key local3/weights not found in checkpoint

    解决办法 原文 https://www.jianshu.com/p/2de8e01af88d with tf.Session() as sess: tf.get_variable_scope().re ...

  5. 刚注册blog,先来刷个存在

    我想以后能够走数字ic设计的道路,努力复习考研,努力提升专业素养,2017加油!青春加油!

  6. 【java设计模式】-07适配器模式

    适配器模式 定义: 将一个类的接口转换成客户希望的另外一个接口.适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作. 类型: 结构型模式 应用实例: 1.JAVA JDK 1.1 提供 ...

  7. django 快速实现注册(四)

    一.创建项目与应用  #创建项目fnngj@fnngj-H24X:~/djpy$ django-admin.py startproject mysite3fnngj@fnngj-H24X:~/djpy ...

  8. 微擎转移服务器后,出现 require()错误,解决方案

    微擎中切换服务器后出现该问题,有可能是导致配置的问题

  9. ReSharper “Cannot resolve symbol” even when project builds

    ReSharper “Cannot resolve symbol” even when project builds   This worked for me (VS2012u4, R# 7.1.3) ...

  10. EBS 查看输出HTML报表问题总结

    问题一: 请求输出格式为HTML(如下图,默认浏览器输出),希望 查看输出 的时候能够实现excel输出. 解决方法: 路径:系统管理员/安装/浏览器选项 注:维护如下记录 文件格式:HTML    ...