POJ 2411 Mondriaan's Dream (状压DP)

原创 2014年08月01日 22:25:15
题目类型  状压DP

题目意思
给出一个 n * m (1 <= n, m <= 11)的空白矩阵 问用 1×2 或 2×1 的小矩阵填満整个空白矩阵的方法数有多少个

解题方法
由于行和列最多只有11 所以可以用状态压缩 把一行的放置状态压缩为一个整数然后进行dp
dp[i][j] -> 前i行 第i行状态为j的方法数有多少个
其中状态 j 的规则 : 对于第i行 某一位上如果是被 1 * 2 (即横放)的小矩阵覆盖 或 被 2*1的小矩阵的下面一格覆盖 , 则这一位为 1 其他情况这一位为 0 
这样设计规则的话 第 i-1 行向 第 i 行转移时 (第 i 行的状态只和第 i-1 行状态有关和i-1上面的行均无关系, 因为那些行的状态影响不了第 i 行)
如果第 i-1行有0状态位的话 那么第 i 行对应位肯定要置为 1 (即放置一个2×1的小矩阵) 然后就可以枚举第 i 行其他未设状态的位的情况 (可以用DFS)
其他位这时只有一种放置情况就是连续两格放一个 1*2 的小矩阵 (因为放置2×1的小矩阵的话这一位依然是0相当于没放, 这一个情况是会被下一行
放置一个 2*1的小矩阵所考虑的) 
详细转移过程看代码 可以用滚动数组优化内存

参考代码 - 有疑问的地方在下方留言 看到会尽快回复的
#include <iostream>
#include <cstdio>
#include <cstring>

using namespace std;

typedef long long LL;
LL dp[2][2100];
bool vis[20];
int m, now;

void DFS(int i, int j) {
	if(i == m) {
		int tmp = 0;
		for( int k=0; k<m; k++ ) if(vis[k]) tmp += (1<<k);
		dp[now^1][tmp] += dp[now][j];
		return ;
	}
	if(i+1 < m && vis[i] == false && vis[i+1] == false) {
		vis[i] = vis[i+1] = true;
		DFS(i+2, j);
		vis[i] = vis[i+1] = false;
	}
	if(i < m) DFS(i+1, j);
}

int main() {
	int n;
	while(scanf("%d%d", &n, &m), n || m) {
		now = 0;
		memset(dp, 0, sizeof(dp));
		dp[now][(1<<m)-1] = 1;  //边界值, 刚开始假设最上面一行上面有一行已经填满的行
		for( int i=0; i<n; i++ ) {
			for( int j=0; j<(1<<m); j++ ) { // 枚举第 i-1 行的状态去更新第 i 行, 第-1行就是刚刚的边界值
				if(dp[now][j] == 0) continue;
				memset(vis, 0, sizeof(vis));
				for( int k=0; k<m; k++ ) {
					if((j & (1<<k)) == 0) vis[k] = true; // 首先把 要放置 2×1矩阵的先放了
				}
				DFS(0, j); // 再枚举放 1*2矩阵的
			}
			now ^= 1;  //滚动数组优化内存
			for( int j=0; j<(1<<m); j++ ) dp[now^1][j] = 0;
		}
		cout<<dp[now][(1<<m)-1]<<endl; // 注意要用 long long
	}
	return 0;
}


【POJ2411】Mondriaan's Dream-状态压缩DP(插头DP?)

【POJ2411】Mondriaan's Dream-状态压缩DP(插头DP?)
  • Maxwei_wzj
  • Maxwei_wzj
  • 2017年03月20日 17:46
  • 259

poj2411 Mondriaan's Dream 插头dp做法

Mondriaan's Dream Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 11379...
  • smz436487
  • smz436487
  • 2014年07月25日 13:56
  • 251

poj2411--Mondriaan's Dream(状压dp+dfs)

Mondriaan's Dream Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 12315...
  • u013015642
  • u013015642
  • 2015年02月04日 20:49
  • 837

poj 2411 Mondriaan's Dream 【dp】

题目:poj 2411 Mondriaan's Dream 题意:给出一个n*m的矩阵,让你用1*2的矩阵铺满,然后问你最多由多少种不同的方案。 分析:这是一个比较经典的题目,网上...
  • y990041769
  • y990041769
  • 2014年10月09日 07:46
  • 1337

POJ2411:Mondriaan's Dream(状态压缩)

Description Squares and rectangles fascinated the famous Dutch painter Piet Mondriaan. One night, a...
  • libin56842
  • libin56842
  • 2014年05月04日 22:44
  • 2685

poj2411Mondriaan's Dream题解

题目大意:给出h*w(1≤h、w≤11)的方格棋盘,用1*2 的长方形骨牌不重叠地覆盖这个 棋盘,求覆盖满的方案数。 输入文件包含多组数据。 每组数据有一行,两个正整数h,w。 输入结束标志为...
  • qq_27138357
  • qq_27138357
  • 2015年08月01日 17:43
  • 467

POJ-2411-Mondriaan's Dream-轮廓线dp(插头dp)

题意:在n*m的方格里铺1*2的骨牌,有多少种可能,首先可以排除一些特殊情况,n*m是奇数,就是0 n或m是1就是1(已经排除n*m的情况)。然后就和我之前写的hdu1992的插头dp一样 #in...
  • lyc1635566ty
  • lyc1635566ty
  • 2016年08月09日 00:31
  • 418

poj 2411 Mondriaan's Dream(状态压缩dp)

Mondriaan's Dream Description Squares and rectangles fascinated the famous Dutch painter P...
  • u014634338
  • u014634338
  • 2015年11月24日 17:27
  • 888

POJ2411——Mondriaan's Dream(轮廓线dp入门)

Mondriaan's Dream Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 1520...
  • say_c_box
  • say_c_box
  • 2016年08月03日 20:12
  • 434

poj 2411 Mondriaan's Dream(状压dp)

题目链接题目描述: Mondriaan’s Dream Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 15058...
  • fouzhe
  • fouzhe
  • 2016年07月30日 16:29
  • 161
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:POJ 2411 Mondriaan's Dream (状压DP)
举报原因:
原因补充:

(最多只允许输入30个字)