ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

2.10 模拟赛总结

2022-05-29 19:31:07  阅读:157  来源: 互联网

标签:总结 状态 导出 子图 边缘 2.10 我们 模拟 关键点


2.10 模拟赛总结

A. 希望

题意

给一张 \(N\times M\) 的网格图,图中存在若干关键点,其中关键点一定不在图的最左或最右两列。

你需要走一条包含点 \((1,1)\) 的欧拉回路,满足:

  1. 该回路经过所有关键点;
  2. 只有在图的最左边或最右边两列时可以沿纵向走,在任意时刻都可以沿横向走。

求路径的最小长度。

\(N\le10,M\le50\)。

做法

我们记图中第一列和最后一列的所有点叫边缘点。

注意到若某个关键点被经过了,则其所在的那行里,一定存在一个边缘点被经过了一次,

因为对于这一行内的一个关键点,只有到达了这一行的边缘点后,才可能沿横向走到该关键点。

同时,当每个边缘点是否被经过的状态确定后,不同行内部如何抉择是互不影响的,

那我们现在来讨论一下,对于具体的一行里两个边缘点状态的所有可能,分别该如何决策。

显然,一行内的一个关键点不会被经过多次,否则我们一定可以将方案调整成只经过一次且会更优,

而我们进入行的途径只有边缘点,故我们必然分别从两边缘点往行内走 \(x\in[0,m]\) 步,

再返回当前边缘点或者到达另一端的边缘点后继续沿纵向行走。

而当边缘点未经过过时需满足步数 \(x=0\),且两边走的步数之和小于 \(m\)。

形式上的,我们记该行左右两个边缘点分别是 \(u\) 和 \(v\),如果一个点 \(p\) 曾被经过,则其状态 \(s(p)=1\)。

首先,如果 \(s(u)=1\),则我们可以选择从 \(u\) 出发到该行最右端的关键点再回到 \(u\) 点或继续走到底;

其次,如果 \(s(v)=1\),则我们可以选择从 \(v\) 出发到该行最左端的关键点再回到 \(v\) 点或继续走到底;

最后,如果 \(s(u)=s(v)=1\),则我们可以选择分别从 \(u,v\) 出发,分别到达一对相邻关键点再返回。

当然,如果该行内没有关键点,我们也可以选择不管这一行。

又因为不同行内部如何抉择是互不影响的,

所以容易想到的是利用 状压DP 的思想,即记录当前坐标以及当前每一行的行走情况来求解。

具体来说,我们设计一个含有 \(O(N5^N)\) 个状态的 状压DP,即:

记 \(f(i,j,S)\) 代表当前在第 \(i\) 行的第 \(j\) 个边缘点,其中第 \(t\) 行的状态是 \(S\) 在五进制下的第 \(t-1\) 位,

该位的五种不同的值,分别代表了该行:

从未走过,被横穿了一次,左边缘点曾被经过,右边缘点曾被经过,两边缘点都曾被经过。

这样的话,我们只需要处理每种状态是否可能出现以及出现这种状态的花费,

最后在额外计算每行没有处理过的花费即可。

但上述方法并不能通过,而实际上这个做法还有优化空间。

但是我们发现,在转移时,下列三种选择对原状态造成的影响是类似的:

横穿一行,只从左边缘点进入并返回,以及只从右边缘点进入并返回。

我们发现,这三种选择都让当前一整行不再需要考虑,而唯一的区别是最后新到达的边缘点位置,

故我们可以考虑不单独记录被横穿,而是记录一个数量为 \(4^N\) 的状态,其中第 \(t\) 行对应的状态有:

从未走过,左边 / 右边走了一部分但没有走完整行,整行的关键点全走了一次。

这样的状态就显然是是完备且可以转移的了,

时间复杂度为 \(O(N^24^N)\),空间复杂度为 \(O(N4^N)\)。

C. 命运

题意

给一张 \(N\) 个点 \(M\) 条边的无向图,请求出图的所有满足不存在三元环的点导出子图个数。

\(N,M\le60\)。

做法

首先,暴力的做法是枚举原图中每个点的状态,即该点是否出现在导出子图中,

再对每个导出子图暴力的统计其是否包含三元环,这样的复杂度是 \(O(2^NN^3)\) 的。

我们考虑优化这个暴力,一个很灵巧的想法是考虑能否只枚举一部分点而达到同样的效果。

那假设我们只枚举了点集 \(S\) 中的点,记不在 \(S\) 中的点集为 \(T\),我们考虑 \(T\) 满足什么性质时能正确计数。

我们发现,如果 \(T\) 是若干个树,环,或链这样的一些特殊结构时,我们就可以采用 DP 来计数,

那也就是说,我们只要能恰当的去选这个 \(S\) 集合,

使得 \(S\) 的大小足够小,且 \(T\) 中只有我们希望出现的结构,那么这个问题就解决了。

那最终的问题就是如何选 \(S\) 集合,我们只需要采用如下的方法即可:

我们建一张新图 \(G\),初始为原图,我们一次次从将 \(G\) 中所有度数大于 \(2\) 的点和与其相连的边删除,

最后无法从 \(G\) 中删点时,所有我们删去的点集就是我们需要的 \(S\) 的一个足够优的解。

为什么?首先,这样得到的 \(S\) 对应的 \(T\) 一定只存在若干个链和环,原因是所有点的度数都小于 \(3\),

而只有链和环能满足这个度数的要求,而因为一次删点的同时会伴随着删至少 \(3\) 条边,

故总删边次数不超过 \(\frac{M}{3}\) 次,故 \(S\) 的大小最大也就是 \(\frac{M}{3}\)。

那么,我们的时间复杂度就是 \(O(2^{\frac{M}{3}}N)\) 的,已经足以通过本题。

最后,我们讨论怎么使用 DP 来对 \(T\) 计数,这个是好做的,具体来说:

首先,每个 \(T\) 中的连通块是独立的,我们可以分开计数,最后再把方案数乘在一起;

而对于一个连通块,其只能是一条链或环,我们考虑对 \(T\) 方案的限制只有如下两种:

其一是,一个 \(S\) 中出现在导出子图中的点与 \(T\) 中的一对相邻点分别有边,

则这对点不能同时出现在导出子图中,

其二是,一对 \(S\) 中出现在导出子图中的相邻点与 \(T\) 中的一个点分别有边,

则这个 \(T\) 中的点不能出现在导出子图中。

也就是说,在枚举 \(S\) 中点的状态后,我们对 \(T\) 的限制只有一个点不能选,或一对相邻点不能同时选。

而这些限制在链或环上都是好处理的,我们直接 DP 计数即可。

标签:总结,状态,导出,子图,边缘,2.10,我们,模拟,关键点
来源: https://www.cnblogs.com/GaryH/p/16324673.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有