其他分享
首页 > 其他分享> > 2.10 模拟赛总结

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