zoukankan      html  css  js  c++  java
  • uoj76

    有趣的题目。

    先考虑完全图怎么做。

    假设只有1个人,显然这个人会直接开枪。

    只有2个人,每个人会先假设自己的狗没有生病,观察1天。如果这样子没有枪声,那么情况就不是“自己的狗没有生病,且我看到的狗都生病了”,而是:“自己的狗生病了,且我看到的狗都生病了”,就会同时开枪。

    多个人同理。设$f[i]$表示i个人开枪的天数。则可以得到:每个人先观察$f[i-1]$天,看看其他$i-1$人有没有出现枪声。如果没有,那么说明情况就不是“自己的狗没有生病,且我看到的狗都生病了”,而是:“自己的狗生病了,且我看到的狗都生病了”,所以会开枪,所以$f[i]=f[i-1]+1$,得到$f[i]=i$。可以直接使用组合数计算答案。

    不是完全图可以采用类似的思路。设$f[s]$表示$s$集合内的所有人的狗患病,开枪的最早时间。则枚举$s$集合的每一个人,最后集合的答案就是所有人的答案的$min$值

    设定多个集合$t$,在集合$t$中,现在这个人看的到的人的状态保持原状,看不到的状态任意选。实际上,看不到的人的状态只能猜,所以这个人的贡献就是所有$f[t]$的最大值。

    在转移形成环时说明“现在的所有点的依赖状态都没有确定,无法确定自己的狗是否患病”,所以状态转移dag的环上的点不会被记入。

    这样子可以拿到30分。

    后面的一些点要$O(2^n*n)$级别的算法。注意到当$s<=t$时$f[s]>=f[t]$,于是转移复杂度降到$O(1)$。(这个性质后面会证明)

    后面$n$较大,只能使用多项式级别算法解决。

    建出原图的补图。证明一个引理:这个图上删除所有环,答案一样。

    考虑一个点的狗生病的情况,若生病,则这个点是黑点,否则是白点。

    原因是:考虑这个转移:转移就是把当前状态删除一个点,然后把这个点的某些直接后继染黑。

    当图是dag时,则染黑的点的拓扑序都大于现在这个点,所以不会形成环。

    当图不是dag时,则存在这么一种方案:把现在的点可以走到环的点染黑,直到当前状态走到环。把其他点依次删除,直到只剩下现在这个点。绕着环走,肯定能够走重复。

    于是可以把环消掉后统计答案。

    又有一个引理:答案等于现在所有点的黑点的可以到达的点数。

    证明可以使用归纳法。在原图上计算它可以到达的状态的答案。则由于归纳假设,把当前答案的点的所有后继都染黑是最优的(顺便把上面提到的引理证明了)

    考虑现在把一个没有其他点能够到达的点变成白色,则答案就是所有点可以到达的点数-1

    把一个有其他点能够到达的点变成白色,则答案就是所有点可以到达的点数

    前者最小,所以现在的f值就是所有点可以到达的点数。

    考虑一个点的贡献,它的贡献分2类

    1.能够到达它的点。假设这些点有v个,则答案就是$2^v-1$(因为前面的v个点至少要选择一个,所以方案要-1)

    2.不能到达它的点可以任意选,答案就是$2^{n-v}$

    第2问答案就是$2^{无法到达的点数}$,原因是考虑包含这个点的dp值要是最小,则由于上面的证明过程,能够到达它的点都要是白色。

    于是这道题就做完了,时间复杂度$O(frac{n^3}{64})$

  • 相关阅读:
    codevs 1115 开心的金明
    POJ 1125 Stockbroker Grapevine
    POJ 2421 constructing roads
    codevs 1390 回文平方数 USACO
    codevs 1131 统计单词数 2011年NOIP全国联赛普及组
    codevs 1313 质因数分解
    洛谷 绕钉子的长绳子
    洛谷 P1276 校门外的树(增强版)
    codevs 2627 村村通
    codevs 1191 数轴染色
  • 原文地址:https://www.cnblogs.com/cszmc2004/p/12383028.html
Copyright © 2011-2022 走看看