简单状压dp的思考 - 最大独立集问题和最大团问题 - 壹

本文参考:CPH ,USACO Guide
(大佬请越过,这是初学笔记,不要吐槽内容)
前置知识:位运算基础,动态规划基础

介绍

状态是元素的子集的动态规划算法,可以用位运算来高效的优化。
那么第一道题就应声而来:

哈密顿航班

我觉得这道题会花费很长时间,但是这题不算难,首先要自己尝试。


题目意思是给定一个很小的图,从\(1\)号点到\(n\)号点,每个点恰好走一次有几种方案?
看过这道题,你是否想到了旅行商问题?没错,这是一个没有保证正确的多项式时间复杂度的算法的问题。好吧,至少方向是有了。\(\mathcal O(n!)\)枚举,这是一个很贴合\(n\)范围的算法。但是显然他还需要再快一点。
不去思考如何优化,一般的思路是考虑在枚举中我们浪费了哪些时间。如果这个算法还可以做最优,那么一定是有哪一些重复计算。因为动态规划的本质就是利用记忆化来减少重复计算。在不考虑动态规划的情况下,大多数暴力算法也可以先考虑哪些计算重复。
那么在这个哈密顿航班的问题里边,我们发现如果固定了一些点集和一个结尾,就能根据它算出所有点。
如果用动态规划的思路来思考的话,如果我们已经求得了点集S从1走到i的答案,那么其他答案就可以由这个状态推出。因为在这个问题里面每个状态只需要知道走到哪里和还有哪些点需要走。这道题就是这么做的。
这样我们把复杂度优化到\(\mathcal O(2^n n)\)级别。

练习

CF1316E Team Building
USACO Gold Uddered but not Herd
这两道题都是推荐的简单但比较创新的状压DP。

深入

最大独立集问题

在一张比较小的图中选择最大的点集使得选出来的点之间任意两点在原图没有边。图的点的数量小于等于40。
首先可以把原题转化成另一个问题,建立原图的补图,就是说点之间有边变无边,无变边有边。根据题意,我们可以把题目转化成求补图的最大团问题(MCP, Maximum Clique Problem)。团可以理解成为一个是完全图的子图。
其实这个DP不是很好考虑。而且感觉如果已经求出了一个子图的最大团,这个最大团未必包含在子图增加一个点后的新图的最大团里面,因为一个子图的最大团可能有多个。而且只存储最大团的数量也不是一个好办法,因为这样没有办法转移方程。
以上这种考虑完全是基于,每次DP在原来子图基础上扩展一个点这样的思路。那么可以切换一下思路。那么考虑扩展之后的子图最大团,这个最大团去掉一个点会如何。我们让动态规划数组存储子图中最大团的点集,也就是说动态规划数组中也是一个状压。
那么再来细细扩充一下刚才的思路。假设当前要求子图最大团的子图的点集为S。单纯的用 \(F[S]\) 表示子图中的一种最大团解答方案。考虑S中的一个点k,如果这个点在最大团中,那么 \(F[S]=F[S中与k相连的点集] \bigcup {k}\),否则即为 \(F[S/{k}]\) ,取两个里面边数更多的一种方案。因为状态方程设置的是任意一种最大团方案,所以不用担心。

但是这样复杂度为 \(\mathcal O(2^n)\)\(\mathcal O(2^n n)\),还需要进一步优化。

注释:这是我本人在USACO Guide上的题解

posted @ 2022-06-28 21:30  Reiss  阅读(91)  评论(0编辑  收藏  举报