【题目分析】

用1*2的牌铺满n*m的格子。

刚开始用到动规想写一个n*m*2^m,写了半天才知道会有重复的情况。

So Sad。

然后想到数据范围这么小,爆搜好了。于是把每一种状态对应的转移都搜了出来。

加了点优(gou)化(pi),然后poj上1244ms垫底。

大概的方法就是考虑每一层横着放的情况,剩下的必须竖起来的情况到下一层取反即可。

然后看了 《插头DP-从入门到跳楼》 这篇博客,怒抄插头DP

然后16ms了,自己慢慢YY了一下,写出了风(gou)流(pi)倜(bu)傥(tong)的代码

UPD:发现完全不需要轮廓线,直接把轮廓线断开一小段就可以转移了,更加坚定自己的算法渣了

【代码】

状压DP

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define F(i,j,k) for (int i=j;i<=k;++i)
#define D(i,j,k) for (int i=j;i>=k;--i)
#define ll long long
ll dp[12][1<<12];
int pos[12],n,m,to[1<<12];
void print(int x){F(i,0,m-1)printf("%d",(x>>i)&1);}
void dfs(int x)
{
if (to[x]) return ;
to[x]=1;
F(i,0,m-2)
if ((!(x&pos[i]))&&(!(x&pos[i+1])))
dfs(x|pos[i]+pos[i+1]);
}
int main()
{
while (scanf("%d%d",&n,&m)!=EOF&&n&&m)
{
memset(dp,0,sizeof dp); int all=(1<<m)-1;
F(i,0,m) pos[i]=1<<i; dp[0][(1<<m)-1]=1;
F(i,0,n-1)
{
F(j,0,(1<<m)-1)
{
memset(to,0,sizeof to);
int aim=j^all; dfs(aim);
F(k,0,(1<<m)-1)
if (to[k]) dp[i+1][k]+=dp[i][j];
}
}
printf("%lld\n",dp[n][(1<<m)-1]);
}
}

  插头DP

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std; long long dp[2][1<<11]; int main()
{
int n,m;
while(scanf("%d%d",&n,&m),(n||m))
{
int total=1<<m;
int pre=0,now=1;
memset(dp[now],0,sizeof(dp[now]));
dp[now][0]=1; for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
{
swap(now,pre);
memset(dp[now],0,sizeof(dp[now])); for(int S=0;S<total;S++) if( dp[pre][S] )
{
dp[now][S^(1<<j)]+=dp[pre][S];
if( j && S&(1<<(j-1)) && !(S&(1<<j)) )
dp[now][S^(1<<(j-1))]+=dp[pre][S];
}
} printf("%lld\n",dp[now][0]);
}
}

  自己写的代(gou)码(pi)

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define ll long long
#define F(i,j,k) for (int i=j;i<=k;++i)
ll dp[2][1<<12];
int n,m;
void print(int x)
{F(i,0,m)printf("%d",(x>>i)&1);}
int main()
{
while (scanf("%d%d",&n,&m)!=EOF&&n&&m)
{
if (n<m) swap(n,m);
int now=1,pre=0;
memset(dp[now],0,sizeof dp[now]);
dp[now][0]=1;
F(i,0,n-1)
F(j,0,m-1)
{
now^=1;pre^=1;
memset(dp[now],0,sizeof dp[now]);
F(s,0,(1<<(m+1))-1) if (dp[pre][s])
{
if ((s&(1<<j))&&!(s&(1<<(j+1)))) dp[now][s^(1<<j)]+=dp[pre][s];
if (!(s&(1<<j))&&!(s&(1<<(j+1)))) dp[now][s^(1<<j)]+=dp[pre][s],dp[now][s^(1<<(j+1))]+=dp[pre][s];
if (!(s&(1<<j))&&(s&(1<<(j+1)))) dp[now][s^(1<<(j+1))]+=dp[pre][s];
}
if (j==m-1)
{
now^=1;pre^=1;
memset(dp[now],0,sizeof dp[now]);
F(s,0,(1<<m)-1) if (dp[pre][s]&&!(s&(1<<m)))
dp[now][(s<<1)&((1<<(m+1))-1)]+=dp[pre][s];
}
}
printf("%lld\n",dp[now][0]);
}
}

POJ 2411 Mondriaan's Dream ——状压DP 插头DP的更多相关文章

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

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

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

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

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

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

  4. POJ 2411 Mondriaan's Dream 插头dp

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

  5. POJ 2411 Mondriaan's Dream/[二进制状压DP]

    题目链接[http://poj.org/problem?id=2411] 题意:给出一个h*w的矩形1<=h,w<=11.用1*2和2*1的小矩形去填满这个h*w的矩形,问有多少种方法? ...

  6. POJ 2411 Mondriaan's Dream:网格密铺类 状压dp

    题目链接:http://poj.org/problem?id=2411 题意: 给你一个n*m的网格 (1<=n,m<=11) ,往里面铺1*2或2*1的砖块,问你铺完这个网格有多少种不同 ...

  7. POJ 2411 Mondriaan's Dream 【状压Dp】 By cellur925

    题目传送门 这道题暑假做的时候太模糊了,以前的那篇题解大家就别看了==.今天再复习状压感觉自己当时在写些什么鸭.... 题目大意:给你一个\(n\)*\(m\)的棋盘和许多\(1*2\)的骨牌,骨牌可 ...

  8. [poj 2411]Mondriaan's Dream (状压dp)

    Mondriaan's Dream Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 18903 Accepted: 10779 D ...

  9. POJ 2411 Mondriaan's Dream (状压DP,骨牌覆盖,经典)

    题意: 用一个2*1的骨牌来覆盖一个n*m的矩形,问有多少种方案?(1<=n,m<=11) 思路: 很经典的题目,如果n和m都是奇数,那么答案为0.同uva11270这道题. 只需要m个b ...

随机推荐

  1. mac系统连接Android手机

    1. 打开终端,输入:system_profiler SPUSBDataType,查看Mac系统所有USB设备信息,找到相应的厂商Vender ID 2.输入echo "Vender ID& ...

  2. JS判断两个对象相同属性的属性值是否相等

    function isObjectValueEqual(a, b) { var aProps = Object.getOwnPropertyNames(a); var bProps = Object. ...

  3. ZOJ 3466 The Hive II (插头DP,变形)

    题意:有一个n*8的蜂房(6边形的格子),其中部分是障碍格子,其他是有蜂蜜的格子,每次必须走1个圈取走其中的蜂蜜,在每个格子只走1次,且所有蜂蜜必须取走,有多少种取法? 思路: 以前涉及的只是n*m的 ...

  4. (转)MyBatis框架的学习(二)——MyBatis架构与入门

    http://blog.csdn.net/yerenyuan_pku/article/details/71699515 MyBatis框架的架构 MyBatis框架的架构如下图: 下面作简要概述: S ...

  5. (六)使用Docker镜像(下)

    1. 创建镜像 创建镜像的方法有三种: 基于已有镜像的容器创建 基于本地模板导入 基于Dockerfile创建 1.1 基于已有镜像的容器创建 该方法主要是使用docker commit命令,其格式 ...

  6. 10.字符串str的语法

    1).字符串的索引以及切片 s = 'ABCDLSESRF' #索引 s1 = s[0] print(s1) #A s2 = s[2] print(s2) #C s3 = s[-1] print(s3 ...

  7. Spring根据XML配置文件注入对象类型属性

    这里有dao.service和Servlet三个地方 通过配过文件xml生成对象,并注入对象类型的属性,降低耦合 dao文件代码: package com.swift; public class Da ...

  8. ios之UITabelViewCell的自定义(xib实现2)

    上篇文章介绍了如何用UITableView显示表格,并讲了几种UITableViewCell的风格.不过有时候我们需要自己定义 UITableViewCell的风格,其实就是向行中添加子视图.添加子视 ...

  9. jquery html5 实现placeholder 兼容password ie6

    <style type="text/css"> /* 设置提示文字颜色 */ ::-webkit-input-placeholder { color: #838383; ...

  10. 【单调栈 动态规划】bzoj1057: [ZJOI2007]棋盘制作

    好像还有个名字叫做“极大化”? Description 国际象棋是世界上最古老的博弈游戏之一,和中国的围棋.象棋以及日本的将棋同享盛名.据说国际象棋起源 于易经的思想,棋盘是一个8*8大小的黑白相间的 ...