题意:有一个n*m的棋盘,要求用1*2的骨牌来覆盖满它,有多少种方案?(n<12,m<12)

思路:

  由于n和m都比较小,可以用轮廓线,就是维护最后边所需要的几个状态,然后进行DP。这里需要维护的状态数就是min(n,m)。即大概是一行的大小。每次放的时候,只考虑(1)以当前格子为右方,进行横放;(2)以当前格子为下方进行竖放;(3)还有就是可以不放。

  3种都是不一样的,所以前面的一种状态可能可以转为后面的几种状态,只要满足了条件。条件是,横放时,当前格子不能是最左边的;竖放时,当前格子不能是最上边的。而且要放的时候,除了当前格子,另一个格子也是需要为空才行的。

 //#include <bits/stdc++.h>
#include <iostream>
#include <cstdio>
#include <cstring>
#define pii pair<int,int>
#define INF 0x3f3f3f3f
#define LL long long
using namespace std;
const int N=1e5+;
LL dp[][<<]; LL cal(int n,int m)
{
if(n<m) swap(n,m);
memset(dp, , sizeof(dp));
dp[][(<<m)-]=;
int cur=;
int h=(<<(m-));
for(int i=; i<n; i++)
{
for(int k=; k<m; k++)
{
cur^=;
memset(dp[cur], , sizeof(dp[cur]));
for(int j=; j<(<<m); j++)
{
if( j&h ) dp[cur][(j^h)<<]+=dp[cur^][j]; //最高位为1时,可以不放
if( k && !(j&) && (h&j)) dp[cur][((j&(h-))<<)|]+=dp[cur^][j]; //放横,左边为0,上面为1
if( i && !(h&j) ) dp[cur][(j<<)|]+=dp[cur^][j]; //放竖,上面为0
}
}
}
return dp[cur][(<<m)-];
} int main()
{
freopen("input.txt", "r", stdin);
int n, m;
while(scanf("%d%d",&n,&m), n+m) printf("%lld\n", cal(n,m));
return ;
}

AC代码

  UVA一样的题:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=33787

 //#include <bits/stdc++.h>
#include <iostream>
#include <cstdio>
#include <cstring>
#define pii pair<int,int>
#define INF 0x3f3f3f3f
#define LL long long
using namespace std;
const int N=;
LL dp[][<<N]; LL cal(int n,int m)
{
if(n<m) swap(n,m);
memset(dp, , sizeof(dp));
dp[][(<<m)-]=;
int cur=, h=(<<(m-));
for(int i=; i<n; i++)
{
for(int k=; k<m; k++)
{
cur^=;
for(int j=; j<(<<m); j++) dp[cur][j]=;
for(int j=; j<(<<m); j++)
{
if( j&h ) dp[cur][(j^h)<<]+=dp[cur^][j]; //最高位为1时,可以不放
if( k && !(j&) && (h&j)) dp[cur][((j&(h-))<<)|]+=dp[cur^][j]; //放横,左边为0,上面为1
if( i && !(h&j) ) dp[cur][(j<<)|]+=dp[cur^][j]; //放竖,上面为0
}
}
}
return dp[cur][(<<m)-];
} int main()
{
//freopen("input.txt", "r", stdin);
int n, m;
while(~scanf("%d%d",&n,&m)) printf("%lld\n", cal(n,m));
return ;
}

AC代码

poj 2411 Mondriaan's Dream (轮廓线DP)的更多相关文章

  1. poj 2411 Mondriaan's Dream 轮廓线dp

    题目链接: http://poj.org/problem?id=2411 题目意思: 给一个n*m的矩形区域,将1*2和2*1的小矩形填满方格,问一共有多少种填法. 解题思路: 用轮廓线可以过. 对每 ...

  2. POJ 2411 Mondriaan's Dream 插头dp

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

  3. POJ - 2411 Mondriaan's Dream(轮廓线dp)

    Mondriaan's Dream Squares and rectangles fascinated the famous Dutch painter Piet Mondriaan. One nig ...

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

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

  5. Poj 2411 Mondriaan's Dream(压缩矩阵DP)

    一.Description Squares and rectangles fascinated the famous Dutch painter Piet Mondriaan. One night, ...

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

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

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

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

  8. Mondriaan's Dream 轮廓线DP 状压

    Mondriaan's Dream 题目链接 Problem Description Squares and rectangles fascinated the famous Dutch painte ...

  9. [POJ] 2411 Mondriaan's Dream

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

  10. POJ2411 Mondriaan's Dream 轮廓线dp

    第一道轮廓线dp,因为不会轮廓线dp我们在南京区域赛的时候没有拿到银,可见知识点的欠缺是我薄弱的环节. 题目就是要你用1*2的多米诺骨排填充一个大小n*m(n,m<=11)的棋盘,问填满它有多少 ...

随机推荐

  1. ubuntu 禁止错误信息 report 问题弹出

    发现ubuntu只要出现点问题就会提示要不要report error, 光点cancel就点烦了. 而且今天重新安装了一台ubuntu结果开机就蹦出error, 好烦啊. 下面说个特别有效的解决办法, ...

  2. PHP错题误区

    1,$bool = TRUE;echo gettype($bool);  //这个输出类型:booleanecho is_string($bool);  //这个用echo是不能输出布尔型的,只有va ...

  3. tetrahedron

    题意: 求解一个四面体的内切球. 解法: 首先假设内切球球心为$(x0,x1,x2)$,可以用$r = \frac{3V}{S_1+S_2+S_3+S_4}$得出半径, 这样对于四个平面列出三个方程, ...

  4. 20个Flutter实例视频教程-第06节: 酷炫的路由动画-2

    博客地址: https://jspang.com/post/flutterDemo.html#toc-94f 视频地址: https://jspang.com/post/flutterDemo.htm ...

  5. msq 表操作与其数据类型

    一:表介绍 表相当于文件, 表中的一条记录就相当于文件的一行内容, 不同的是,表中的一条记录有对应的标题,称为表的字段: id,name, age, sex,称为字段, 其余的一行内容称为一条记录. ...

  6. MyBatis中的RowBounds

    myBatis中实现分页的方式是采用RowBounds这个类,用法如下,xml语句不变 传入两个参数,strat起始行, limit是当前页显示多少条数据,原理是RowBounds在处理分页时,只是简 ...

  7. shader实例(二十二)TexGen-球面贴图SphereMap

    http://blog.sina.com.cn/s/blog_89d90b7c0102vfqz.html 球面贴图一般用于环境反射,如下图(左边为球面贴图,右边为正常贴图),一个镜面水晶球在这只猫的前 ...

  8. git 版本控制(一)

    新建代码库repository 1.在当前目录新建一个git代码库 git init git init projectname 2.下载一个项目,如果已经有了远端的代码,则可以使用clone下载 gi ...

  9. ( 2018 Multi-University Training Contest 2)

    2018 Multi-University Training Contest 2) HDU 6311 Cover HDU 6312 Game HDU 6313 Hack It HDU 6314 Mat ...

  10. bzoj 4318 || 洛谷P1654 OSU!

    https://www.lydsy.com/JudgeOnline/problem.php?id=4318 https://www.luogu.org/problemnew/show/P1654 看来 ...