插头dp?你说的是这个吗?

好吧显然不是......

所谓插头dp,实际上是“基于连通性的状态压缩dp”的简称,最先出现在cdq的论文里面

本篇博客致力于通过几道小小的例题(大部分都比较浅显)来介绍一下这种思路清奇的dp是怎么回事

Part I 定义

何为插头?

插头实际上是一个代称,代指两个格之间的连通性

若dp的某一个状态中,有某相邻的两个格子是联通的(比如说处在同一条路径上、被同一个矩形覆盖blablabla),我们就认为这两个格子之间有插头

举个栗子,格子(1,1)和格子(2,1)联通,那么格子(1,1)就有一个下插头,而格子(2,1)有一个上插头,如下图所示

每一个格子可以有的插头数量随着题目而变

对于一道用路径覆盖棋盘的题目(不相交不重叠的路径)而言,每个格子最多有两个插头:这种情况下表示有一条路径从这个格子的某一个插头的那个方向进来,又从另一个插头的那个方向出去了

例如一条回路的插头表示:

何为轮廓线?

轮廓线就是一条分割线,分隔了dp已经覆盖的状态和暂未覆盖的状态,它是在插头dp的棋盘模型中被定义的

插头dp有两种dp方式:逐行递推和逐格递推,其中逐行递推因为在很多题目中状态过多被弃用

当然也不是说逐行递推就没有用了, 但是本文主要讲逐格递推

逐格递推中,轮廓线是这样的:设当前正在递推的格子是(i,j)

那么轮廓线就是一条从棋盘左边界开始,沿着第i行的格子底部向右延伸至格子(i,j)的左下角,然后向上一格,再一直向右延伸到棋盘右边界

轮廓线的长度是m+1,其中m是列数

对于插头dp的棋盘模型,轮廓线上的不同插头状态就是dp的状态,因此可以引出插头dp棋盘模型的状态定义:

定义$dp\left[i\right]\left[j\right]\left[S\right]$表示如下条件时,插头dp的状态:

当前逐格递推到了第$i$行第$j$列的格子,轮廓线上方的插头状态为$S$,其中$S$的是状态压缩的

轮廓线的一个例子如下图:

其中黄色格子是当前正在递推(也就是正在从黄色格子左边的那个格子往黄色格子转移)的格子,红色的就是轮廓线

轮廓线的上方有m个下插头位置和一个右插头位置

PART II 棋盘模型

棋盘模型是插头dp的最常见(前几年最喜欢考)的方法

大概考法就是给你一个比较小的棋盘(15*15左右?或者更大一点),上面可能有些格子是障碍,然后让你用一些闭合路径啊,哈密顿回路啊或者一些奇奇怪怪的形状来覆盖棋盘上的每一个格子

还有一种考法就是给每个格子赋一个权值,然后让你找一条最优的回路或者路径或者某特定形状之类的

这一类题目有一个关键点:把轮廓线画出来以后,轮廓线上方的会是一些完备的“题目要求的形状”和一些“一头扎到”轮廓线下面,也就是被轮廓线切割的形状,而这些被切割的形状在轮廓线上方的分布我们不清楚,但是我们可以用轮廓线上插头的状态来表示所有情形的和

举个例子,现在有一条轮廓线,轮廓线上面有一些插头。我们现在可能不知道轮廓线上面的情况具体是怎么样的,但是我们根据这些插头就能往下推下面的状态

所以我们只要记录这种插头状态下轮廓线上方的答案,然后往下推就好了

也就是说我们把一个需要dfs找覆盖的问题转化成了一个dp模型~

现在的问题就是,我们怎么表示轮廓线上方的插头的状态呢?

cdq在论文中为我们提供了一个比较好的通解——最小表示法

最小表示法是这样的:对于一类插头可以互相配对的dp问题,我们有以下结论:

设从左到右的四个插头a,b,c,d,其中ac配对bd配对,而ab不配对:这种情况不可能存在

因此此时一定要么ab配对cd配对,要么ad配对bc配对

最小表示法,就是从左到右扫一遍所有插头,并这样操作:

如果这个插头已经被标记过了,就跳过

如果没有,设当前的插头是第i个未标记的插头

将所有当前插头联通的插头标记为i,然后进入下一个插头

这养的方法,由于插头dp本身是基于连通性的,所以一定可行,但是缺点是其时间效率可能较低

因此,对于每一道题,我们在确定最小表示法可以的前提下,可以再多加探索一些别的方法

比如下面这道例题:URAL1519

这道题利用的就是括号序列

又比如这道题:BZOJ2331

这道题利用L形自身的性质定义了插头(我甚至都不确定这道题最小表示法能不能用)

棋盘模型的例题很多,这里列举一些供大家参考

HNOI2007 神奇游乐园

HNOI2004 邮递员

HDU1693 eat the trees

POJ1739 Tony's tour

ZJOI2009 多米诺骨牌 (这个准确来说不是插头dp,但是如果只有要求跨越每一行的话可以插头解决)

这些题目的写法基本都是大同小易,都是共同的,很多题甚至可以用同一份代码过掉

但是一定要多写,因为这样才能让插头dp真正熟记于心,同时处理不同的题目也能加深理解

PART III 直线模型

先鸽着......还没学透

例题:NOI2007生成树计数,GDKOI2018d1t4(大概?)

终于!终于!时隔八个月!博主终于打破了咕咕咕的记录!我把NOI2007生成树计数做了!

然后发现其实能讲的不多......

基础原理

我们知道,插头dp的本质,是“基于连通性的状态压缩dp”

那么对于一类构造图/回路/生成树的题目,我们就可以以对一部分点或者边的连通性的描述作为dp的状态,然后进行转移

举个栗子:NOI2007生成树计数

这道题目利用了给定的图的边的特性,推出了一个状态树比较少的dp,然后套进了矩阵快速幂里面做完。

注意这道题目同样利用了最小表示法,又根据第二类斯特林数的理论得到总的状态数很少

方法特性&&注意事项

这个模型的题目,代码复杂度和讨论复杂度和棋盘模型比起来会少很多,但是它的难点不在于这里

这个模型的难点在于构造出符合“无后效性”“状态不重复不遗漏”的dp状态

同时,要注意到“轮廓线”的概念依然存在于直线模型中,只是它的存在被编辑成了其它的形式,例如上一道例题中的

最后,一定要熟记最小表示法的应用

PART IV 总结

插头dp平时可以见到的题目比较少,但是这并不妨碍插头dp成为众多优秀的dp模型中最具有思维复杂度以及讨论的美感的dp之一

考试中遇到插头dp的概率不大

如果遇到了棋盘模型请谨慎开题,避免全场刚一道导致爆炸;

如果遇到了直线模型,请......结合具体问题分析吧【因为实在是变数很多】

最后,不要学习我把一个知识点咕咕咕了长达八个月的时间>_<

省选算法学习-插头dp的更多相关文章

  1. 省选算法学习-dp优化-四边形不等式

    嗯......四边形不等式的确长得像个四边形[雾] 我们在dp中,经常见到这样一类状态以及转移方程: 设$dp\left[i\right]\left[j\right]$表示闭区间$\left[i,j\ ...

  2. 省选算法学习-数据结构-splay

    于是乎,在丧心病狂的noip2017结束之后,我们很快就要迎来更加丧心病狂的省选了-_-|| 所以从写完上一篇博客开始到现在我一直深陷数据结构和网络流的漩涡不能自拔 今天终于想起来写博客(只是懒吧.. ...

  3. 省选算法学习-回文自动机 && 回文树

    前置知识 首先你得会manacher,并理解manacher为什么是对的(不用理解为什么它是$O(n)$,这个大概记住就好了,不过理解了更方便做$PAM$的题) 什么是回文自动机? 回文自动机(Pal ...

  4. 省选算法学习-BSGS与exBSGS与二次剩余

    前置知识 扩展欧几里得,快速幂 都是很基础的东西 扩展欧几里得 说实话这个东西我学了好几遍都没有懂,最近终于搞明白,可以考场现推了,故放到这里来加深印象 翡蜀定理 方程$ax+by=gcd(a,b)$ ...

  5. [入门向选讲] 插头DP:从零概念到入门 (例题:HDU1693 COGS1283 BZOJ2310 BZOJ2331)

    转载请注明原文地址:http://www.cnblogs.com/LadyLex/p/7326874.html 最近搞了一下插头DP的基础知识……这真的是一种很锻炼人的题型…… 每一道题的状态都不一样 ...

  6. 插头DP学习笔记——从入门到……????

    我们今天来学习插头DP??? BZOJ 2595:[Wc2008]游览计划 Input 第一行有两个整数,N和 M,描述方块的数目. 接下来 N行, 每行有 M 个非负整数, 如果该整数为 0, 则该 ...

  7. 模板:插头dp

    前言: 严格来讲有关dp的都不应该叫做模板,因为dp太活了,但是一是为了整理插头dp的知识,二是插头dp有良好的套路性,所以姑且还叫做模板吧. 这里先推荐一波CDQ的论文和这篇博客http://www ...

  8. 【BZOJ】2331: [SCOI2011]地板 插头DP

    [题意]给定n*m的地板,有一些障碍格,要求用L型的方块不重不漏填满的方案数.L型方块是从一个方格向任意两个相邻方向延伸的方块,不能不延伸.n*m<=100. [算法]插头DP [题解]状态0表 ...

  9. URAL1519 Formula 1 —— 插头DP

    题目链接:https://vjudge.net/problem/URAL-1519 1519. Formula 1 Time limit: 1.0 secondMemory limit: 64 MB ...

随机推荐

  1. Java环境变量搭建(Windows环境)

    变量名:JAVA_HOME 变量值:C:\Program Files (x86)\Java\jdk1.8.0_91        // 要根据自己的实际路径配置 变量名:CLASSPATH 变量值:. ...

  2. sqlldr将txt导入oracle数据库

    注意事项: 1.userid 和 control关键字不要缺少: 2.注意数据库格式:test/test@数据库IP:1521/Oracle8,最后一个是tnsnames中的service_name, ...

  3. Oracle表连接学习笔记

    目录 一.表连接类型 1.1 内连接 1.2 外连接 二.表连接方法 2.1 表连接方法分类 2.2 表连接方法特性区别 @ 一.表连接类型 表连接类型可以分为:内连接.外连接,在看<收获,不止 ...

  4. css3媒体查询中device-width和width的区别

    1.device-width 定义:定义输出设备的屏幕可见宽度. 不管你的网页是在safari打开还是嵌在某个webview中,device-width都只跟你的设备有关,如果是同一个设备,那么他的值 ...

  5. vue组件-使用插槽分发内容(slot)

    slot--使用插槽分发内容(位置.槽口:作用: 占个位置) 官网API: https://cn.vuejs.org/v2/guide/components.html#使用插槽分发内容 使用组件时,有 ...

  6. eclipse projectExplorer视图(以包的方式显示)与navigator视图切换(以文件夹的方式显示)及树状视图与平面视图的切换

    projectExplorer与navigator的切换 projectExplorer视图效果 想要此视图效果步骤如下: 分割------------------------------------ ...

  7. 用jq给img添加error事件

    <img src="xxxx.jpg" alt="" /> <script> $(document).ready(function(){ ...

  8. 第1章 VMware中安装CentOS7

    目录 1.1 下载CentOS7安装包 1.2 VMware中新建虚拟机 1.3 安装操作系统 本章讲解在VMware中安装CentOS虚拟机的步骤.使用的VMware Workstation版本为1 ...

  9. 库函数的使用:sscanf的使用方法

    先贴代码,可以看懂代码的直接看代码: /***************************************************** ** Name : sscanf.c ** Auth ...

  10. Go语言之反射(一)

    反射 反射是指在程序运行期对程序本身进行访问和修改的能力.程序在编译时,变量被转换为内存地址,变量名不会被编译器写入到可执行部分.在运行程序时,程序无法获取自身的信息.支持反射的语言可以在程序编译期将 ...