codeforces GYM 101431E (状态压缩dp+博弈)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/wuxufanzhong/article/details/75269887

Problem E. Vera and Engineering Buildings

状态压缩dp 博弈 codeforces
题目链接

题目大意

有N个建筑构成一棵树(由数据范围可判断),每个建筑都有一个美观值,所有建筑的美观值都互不相同。但Vera不能得知建筑的具体美观值是多少。他每次可以花 ti 个单位时间调查:第i个建筑和所有与i相邻的建筑的相对高低。即若i与k个建筑相邻,分别是 v1,v2,,vk ,花费 ti 时间后就能知道i和 v1 中谁的美观值更高,i和 v2 中谁的美观值更高……

Vera想找一个建筑,它的美观值比所有与它相邻的建筑都要高(极大点)。问Vera至少需要多少时间,才能保证找到这样一个建筑。(Vera可以根据上一次调查的结果来决定下一次调查的建筑)

数据约束: 2N16 1ti108

解答

根据数据范围,应该能看出需要用到状态压缩。我先从样例得到启发,认为跟边是否调查过有关,如果所有边都调查过,那肯定是可以找到的。那是不是只要有一条边的信息没有得到,就不能找到极大点呢?然后我就用了一个错误的证明,得到了错误的结论。

假设还有一条边的信息没有得到,其两个端点是u和v。我们分别以u和v为根,用已经得到信息的边构成两颗树,如果所有父亲结点都比它的孩子大,那么就还未找到极大点,u和v就还需要比较,所以最后一条边的信息也必须知道。问题就变为,选价值和最小的点,选中所有边。做法是对边状态压缩dp。

然而,这样做返回的是Wrong Answer。有以下反例。

这里写图片描述
从左到右编号分别是1-8,每个点的调查时间都是1。如果先调查第3个和第6个点,若美观值用 ai 表示,那么在没有找到极大点的情况下,有以下几种可能性。

  • a2<a3<a4 a5<a6<a7 ,这时 a7 已经大于 a6 ,只有和 a8 的关系未定,而 a8 只有和 a7 有边,所以两者之间必然有一个极大点,只要再调查一次即可。
  • a2<a3<a4 a5>a6>a7 ,这时 a4 a5 都比相邻的其中一个大,两者又相邻,所以也必然存在一个极大点,也只需再调查一次。
  • a2>a3<a4 ,这时比较 a1 a2 即可,总共2次即可找到极大点。
  • 另外的情况,由对称性可得。

由此可见,并不是所有边的信息都要得到,上面错误的证明,没有考虑调查的次序和结果的影响。那么这个问题又该如何做呢?

由特殊到一般,我们假设所有点的调查花费都是1,建筑物构成的是一条链。第一次调查之后,把链分成两块,并且通过相邻的信息可以得到以下两个结论。

  • 如果相邻点>调查点,那么该相邻点所在的块一定存在极大点(可用反证法)
  • 如果相邻点<调查点,那么该相邻点所在的块可以不存在极大点(可用举例法)

由于如果所有相邻点都小于调查点的话,调查点已经是极大点;所以要使调查不停止的话,就至少存在一个相邻点>调查点。我们只要选中一个相邻点>调查点的块,其他块就完全不需要再考虑了。因此,我们就可以得到一个贪心的做法,每次把规模减半。继续考虑细节的话,分成的两块,是取多的那块呢,还是取少的呢?

答案自然是多的。因为题目要求的是保证找到的最少时间,所以如果我是系统的话,我就把极大点放在多的那一块(相邻点>调查点),让少的那一块没有极大点(相邻点<调查点)。

这看起来,是不是有点像博弈?Vera要尽快找到极大点,系统要让Vera找到极大点的时间尽量长,两者用最优策略行动。

对于原题,我们可以枚举调查点 xi ,然后分成几块(同样也是树),系统选一块需要时间最长的一块给Vera。然后Vera在多个 xi 的最大事件中找一个时间最小的,作为最优调查点。dp的状态是集合,可以用二进制压位表示。dp[U]表示调查子集U找到极大点的最小保证时间,状态转移方程如下:

dp[U]=minxU(maxyUand<x,y>Edp[set(U,x,y)]+a[x])

E是边的集合;set(U,x,y)表示,经过y但不经过x的U的最大连通子块。

临界:若某个子状态 Ui 的大小<=1,则dp[ Ui ]=0。

总时间复杂度是 O(2NN2)

AC代码

猜你喜欢

转载自blog.csdn.net/wuxufanzhong/article/details/75269887
今日推荐