首页 > 其他分享 >(轮廓线)插头 DP

(轮廓线)插头 DP

时间:2024-07-07 22:21:57浏览次数:9  
标签:插头 连通 格子 表示法 轮廓线 DP

出自陈丹琦的《基于连通性状态压缩的动态规划问题》。

论文 PDF

一般基于棋盘(方格表)模型。

【(轮廓线)插头 DP】

如果有简单点的例题就好了,但没有找到,那么直接拿插头 DP 模板题吧。

插头 DP 模板题

给定一个方格表,有一些格子放了障碍物,求用一条回路恰好经过所有格子的方案数。\(n,m\le 12\)。

连模板都是黑色

【插头】

因为要研究格子之间的连通性,而每个格子只会与上下左右四个格子连通,所以可以想象在每个格子里有一个中枢;然后这个中枢有上下左右四个可能的插头。

如果一个格子有对应方向的插头,就表示这个格子要和对应方向的相邻格子连通。

再观察到题目中回路的条件。在一条回路中,每个格子的度恰好为 \(2\)。也就是说,每个格子恰好有两个插头。

【连通性的表示】

对于这种数据范围很小的,我们根据以往的经验,应该会想到状压 DP(事实上插头 DP 也只是对状压的优化)。

如果是常见的状压 DP,只需要用状态记录每一行每个格子是否有向下的插头即可;但是这个问题还要考虑格子之间的连通性,因此还要额外压缩一维状态用来记录连通性。

问题来了:怎么把连通性压缩为一个数?

论文中提到三种表示方法,分别是最小表示法、最左表示法和括号表示法。括号表示法暂且按下不表。

最小表示法和最左表示法,其实都是把同一个连通块的元素赋予同一个编号。

  1. 最小表示法:循环 \(i\leftarrow 1\sim n\),如果 \(i\) 有编号,跳过;如果 \(i\) 是障碍物,赋值编号为 \(0\);否则从 \(i\) 搜索一遍,把所有与它连通的都赋予一个新编号。

  2. 最左表示法:如果是障碍物,编号 \(0\);否则编号为它所在连通块最靠左的格子编号。

因为最小表示法比较好写,比较常用,下面都用最小表示法了。

【尝试状压 DP】

看到棋盘、\(n,m\le 12\),不由自主想到状压 DP。本来应该是 \(dp[i][S]\):记录第 \(i\) 行向下连通的状态即可。但是还要额外记录一下连通性,因此状态描述变成 \(dp[i][S_0][S_1]\):\(S_0\) 表示第 \(i\) 行向下连通状态(其实就是记录有没有向下的插头),\(S_1\) 表示第 \(i\) 行内部的连通状态。

(注意 \(i+1\sim n\) 行的格子显然不可能跨越第 \(i\) 行与 \(1\sim i-1\) 行的格子连通,所以这是无后效性的一个状态定义)

在状态转移的时候,枚举 \(S_0\) 可以衍生出的所有后续状态。


我们发现,如果一个格子没有向下的插头,它与其他格子的连通性是没有记录的意义的:因为和它连通必然用到其他格子。所以只需要记录插头的连通情况即可。

而因为我们只记录有插头的地方,所以可以把 \(S_0,S_1\) 直接合并为 \(S\)(把 "有没有插头" 和 "格子连通性" 合并成 "插头连通性")。如果这个位置没有插头,对应位上记录 \(0\),其他地方就用最小表示法。这是一个极大的优化。

【轮廓线/插头 DP】

状压 DP 是一行一行递推的,有没有可能可以按格子递推呢?当然可能。而这就是轮廓线 DP。

轮廓线:把已递推的格子和未递推的格子分开的线。

轮廓线 DP 要求每次可能对下方产生影响的,都是 "边界" 上的格子;而形成回路,显然只有边界上的格子可以连接。注意轮廓线长度为 \(m+1\),如果刚好是一条直线可以认为最右边有一个不存在的空位置。

省略一些过程,轮廓线 DP 的状态描述为:\(dp[i][j][S]\) 表示递推到格子 \((i,j)\),此时轮廓线上插头联通状态为 \(S\)。

那我们把普通状压改成轮廓线获得了什么?

首先显而易见的,空间从 \(O(n2^m)\) 变成 \(O(nm2^m)\) 了。空间多了,但是我们换来了时间的大幅减少。

普通状压 DP 需要从一个状态 \(S\) 枚举下一行格子的状态 \(S'\),是指数级的;但是改成轮廓线之后,我们只需要枚举下一个格子的状态来更新就行了,分类讨论即可。复杂度直接少一个指数级。

(其实把这称作插头 DP 是不太妥当的,但大概因为插头 DP 不上轮廓线做不了吧)

【还能优化?括号表示法】

上面没提到的括号表示法,在这里讲。

我们观察到一个性质:如果有在轮廓线上顺次排列的四个插头 \(a,b,c,d\),且 \(a,c\) 连通,\(b\) 与 \(a,c\) 都不连通,必然 \(b,d\) 不连通。

这让 我们 dxm 联想到括号序列:如果把没有插头的位置标记为空,把一个连通分量在轮廓线上靠左的插头位置标记为左括号,靠右的插头标记为右括号,沿着轮廓线,可以得到一个合法括号序列。

注意不可能一个连通块里有三个插头,因为最后所有插头都连通了,这三个插头就会形成一个回路套回路,不符合题意;也不可能有一个插头不与其他连通。

(这里说回路套回路而不是说多个回路,是因为有的题目是多个回路,但都是简单回路)

而根据括号序列,我们也能还原出轮廓线的状态。

那么我们就可以把原来的不知道多少进制压缩而成的状态,变成稳定的三进制压缩了。\(0\) 是没有插头,\(1\) 是左括号,\(2\) 是右括号。

【实现的方法】

看了上面的分析:简直太恐怖了!

首先就是怎么存储一个高进制/三进制的状态:这道题 \(n,m\le 12\),也就是最多 \(6\) 个连通块。我们可以把六进制改存为八进制,三位三位看;三进制就变成四进制,两位两位看。

主要有两种方法:循环和记忆化广搜。记忆化广搜一般会比循环快两三倍,因为循环实际上有很多无效状态,但是如果是用广搜主动拓展出来的肯定是合法状态。

滚动数组优化:因为 \(dp[i][j][S]\) 只会用到 \(dp[i][j-1][S]/dp[i-1][m][S]\) 作为更新,可以用滚动数组;如果是记忆化广搜,就是滚动的扩展队列。

另外,用括号表示法比不用大概又快两三倍。

标签:插头,连通,格子,表示法,轮廓线,DP
From: https://www.cnblogs.com/FLY-lai/p/18282534

相关文章

  • WPF Behavior InvokeCommandAction Command CommandParameter
    //xaml<behavior:Interaction.Triggers><behavior:EventTriggerEventName="MouseWheel"SourceObject="{BindingElementName=img}"><behavior:InvokeCommandActionCommand="{BindingMouseWheelCmd}"......
  • 时间序列分析:西安GDP 的 ARIMA 分析SAS操作过程(理论知识略)
    目录一、西安GDP的ARIMA分析二、判断序列的平稳性 三、定阶和预测SAS代码附录:一、西安GDP的ARIMA分析通过对某一指标进行短期的ARIMA分析预测,我们能够预见其未来几年的变化趋势.基于这些预测结果,我们可以采取针对性的措施和制定适应性政策,以促进快速且高效的发......
  • DDPM生成人脸代码
    基于DDPM介绍的理论,简单实现DDPM生成人脸,代码如下:utils.pyimportosfromtorch.utils.dataimportDatasetfromtorchvision.transformsimporttransformsimportglobimportcv2classMyDataset(Dataset):def__init__(self,img_path,device):super(My......
  • 最大魅力值-线性dp
    蓝桥云课-最大魅力值#include<iostream>#include<cstring>usingnamespacestd;inta[101];intdp[101][101];intmain(){intn;cin>>n;for(inti=1;i<=n;++i){cin>>a[i];}memset(dp,-10000,sizeof(dp));/......
  • 使用zdppy_api+onlyoffice word文档在线共同编辑,附完整的vue3前端代码和python后端代
    参考文档:https://api.onlyoffice.com/zh/editors/basichttps://api.onlyoffice.com/zh/editors/coedit基本的架构思考:文档表:记录的是文档信息key:这个key可以标识唯一的一个文档,可以是文档的hash值fileType:文档的类型,docx,txt,pdf,其他title:文档的标题,也就是文档的实际......
  • Udp
    Udp协议1.客户端(与服务器不需建立连接)//1.建立socketDatagramSocketdatagramSocket=newDatagramSocket();//2.建立一个包Stringmsg="你好!";InetAddresslocalhost=InetAddress.getByName("127.0.0.1");intpost=9000;//数据,数据起始,数据长度,数据发送地址Datag......
  • P7224 [RC-04] 子集积 (背包 dp + 复杂度优化)
    P7224[RC-04]子集积背包dp+复杂度优化考虑dp。容易想到背包dp,设\(f_{i,j}\)表示考虑了前\(i\)个,当前乘积为\(j\)的方案数。枚举\(a_i\)的倍数转移。复杂度\(O(\sum\limits_{i=1}^n\frac{m}{a_i})\)。如果\(a_i\)互不相同,那么近似于\(O(m\lnm)\)。如果还想......
  • [树形dp]没有上司的舞会
    题目描述UralUralUral大学有N......
  • DP:完全背包问题
    文章目录......
  • 二维dp
    阿里巴巴2023092501题目描述在一个(n×n)的正方形训练场上,每个位置都有一枚硬币。小明从左上角(0,0)出发,跳跃可以按以下方式进行:向右走一步,再向上或向下走两步。向右走两步,再向上或向下走一步。小明不能跳出训练场,也不能往回跳。目标是帮助小明获得尽可能多的硬币......