第一道轮廓线dp,因为不会轮廓线dp我们在南京区域赛的时候没有拿到银,可见知识点的欠缺是我薄弱的环节。

题目就是要你用1*2的多米诺骨排填充一个大小n*m(n,m<=11)的棋盘,问填满它有多少不同的方法。 一个可行的解法就是轮廓线dp。 假设我们从上往下,从左往右去填,那么我们会发现,假如我们当前填的是(i,j)格的时候,在它前面的(i',j')其实是已经确定一定填了的,所以实际上没有填的时候处于轮廓线的部分,在这里没有具体

1 1 1 1
1 1 x x
x x    
       

如上图,当我们填红色的x那一格的时候,前面的(i',j')必然为1,而实际上我们要考虑的是x 的那一部分,这一部分就是所谓的轮廓线,x的取值可能是不确定的,所以我们可以用位压缩表示出xxxx的状态。转移的时候根据的就是三种情况,1是红色的x 已经填了,这个时候不用放,相应的转移情况,还有就是红色的x没填,它可以打横放以及打竖放。

因为用到位压缩,所以要求的是棋盘一定具有窄边框的特性,就是有一维上必须是10左右,由于每一格是一个阶段,每次转移2^m种状态,每种状态转移的复杂度是O(1),所以总体的复杂度是O(n*m*2^m)。

还有一些变形是棋盘上本身就已经有一些障碍,这个只需要在转移的时候多加注意即可,我后面也会做一道试试。

#pragma warning(disable:4996)
#include<iostream>
#include<cstring>
#include<string>
#include<algorithm>
#include<vector>
#include<cmath>
#include<cstdio>
#define ll long long
using namespace std; int n, m;
ll dp[2][1 << 12]; // 二维滚动数组 int main()
{
while (cin >> n >> m &&(n||m))
{
memset(dp, 0, sizeof(dp));
ll *cur, *next;
cur = dp[0]; next = dp[1];
cur[0] = 1;
for (int i = 0; i < n; i++){
for (int j = 0; j < m; j++){
memset(dp[(i*m+j+1)&1], 0, sizeof(dp[(i*m+j+1)&1]));
cur = dp[(i*m + j) & 1]; next = dp[(i*m + j + 1) & 1];
for (int k = 0; k < 1 << m; k++){
// 如果已经放了,那就直接转移
if ((k >> j) & 1){
next[k & ~(1 << j)] += cur[k];
}
else{
// 尝试横放
if (j + 1 < m && !(k >> (j + 1) & 1)){
next[k | 1 << (j + 1)] += cur[k];
}
// 尝试竖放
if (i + 1 < n){
next[k | 1 << j] += cur[k];
}
}
}
}
}
printf("%lld\n", next[0]);
}
return 0;
}

POJ2411 Mondriaan's Dream 轮廓线dp的更多相关文章

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

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

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

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

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

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

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

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

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

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

  6. poj2411 Mondriaan's Dream【状压DP】

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

  7. [Poj2411]Mondriaan's Dream(状压dp)(插头dp)

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

  8. poj2411 Mondriaan's Dream[简单状压dp]

    $11*11$格子板上铺$1*2$地砖方案.以前做过?权当复习算了,毕竟以前学都是浅尝辄止的..常规题,注意两个条件:上一行铺竖着的则这一行同一位一定要铺上竖的,这一行单独铺横的要求枚举集合中出现连续 ...

  9. POJ1185 炮兵阵地 和 POJ2411 Mondriaan's Dream

    炮兵阵地 Language:Default 炮兵阵地 Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 34008 Accepted ...

随机推荐

  1. ie8中使用placeholder

    placeholder 是 html5 中的新属性,考虑到还有不少 ie8 的用户,所以找了一个 ie8 的 placeholder 的补丁,如下: <script type="tex ...

  2. chrome源码编译常见的错误解决

    最近编译chrome浏览器源码时,下载源码和一般的设置,网络中都有说明,而且一般的说明都是类似的,然后都说编译成功了,但本人没有试成功,碰到常见的2个错误,记录下,不知道大家碰到没有. 1.pytho ...

  3. gcc常用命令介绍

    GCC 全称是 GNU C Compiler,是gnu中最流行的c & c++编译器,下面我们看一下一些主要的参数使用方法. 对于一个源文件可以直接生成可执行文件 gcc test.c 默认生 ...

  4. mysql颠覆实战笔记(四)--商品系统设计(一):商品主表设计

    版权声明:笔记整理者亡命小卒热爱自由,崇尚分享.但是本笔记源自www.jtthink.com(程序员在囧途)沈逸老师的<web级mysql颠覆实战课程 >.如需转载请尊重老师劳动,保留沈逸 ...

  5. 【风马一族_Java】如何使用ACSLL表的值,

    ------------------------------------------------------------------------------ 一,依次ACSLL表的值 将自然数赋值给c ...

  6. DEDECMS中,文章页直接输出字段名

    文章页中,可直接输出字段名

  7. 《samba服务配置的文本》

    创建简单的samba服务器 samba  很少用于互联网 /大部分用于局域网  网页更新/ 首先看下你是否安装后了samba. rpm -qa | grep samba samba的简介 1)samb ...

  8. Ubuntu14.04 开启MySQL的remote access

    一旦开启MySQL的remote access, 即可实现在windows系统下连接ubuntu下的mysql 步骤如下: sudo vim /etc/mysql/my.cnf bind-addres ...

  9. linux下dup/dup2函数的用法

    系统调用dup和dup2能够复制文件描述符.dup返回新的文件文件描述符(没有用的文件描述符最小的编号).dup2可以让用户指定返回的文件描述符的值,如果需要,则首先接近newfd的值,他通常用来重新 ...

  10. BootStrap简介及应用要点

    BootStrap简介 BootStrap是基于HTML.CSS和JavaScript的框架,使你只需要写简单的代码就可以很快的搭建一个还不错的前端框架,他是后端程序员的福音,使他们只需要专注业务逻辑 ...