[PKUWC2018]随机算法

[PKUWC2018]随机算法

给定一张图,大小为 \(n\),边数为 \(m\)

现执行一个算法:

  • 随机一个排列 \(p\)
  • 然后令 S 为空集,依次考虑排列 \(p\),对于 \(\forall i,1\le i\le n\),检查 \(S\lor p_i\) 是否为独立集,如果是则加入 \(p_i\)

求这个算法的期望正确概率。

\(\rm Sol:\)

先考虑一个自动机来识别原算法构成独立集是谁。

我们建 \(dp[S]\) 数组表示状态 \(S\) 是否为独立集。

我们先不关注是否是排列的问题,仅考虑依次加入一些元素然后判定上述算法构成的独立集是啥。

考虑加入一个字符之后的转移状态 \(Go(S,p)\),显然只有两种情况:

  • \(S\to S',S\to S\)

对于前者意味着自动机上进行了转移,表示加入了一个合法的元素,我们只关注后者,显然后者有两种:一类是加入了原来在 S 中存在的元素,一类是加入了原来不存在的元素。

如果是第一类,那么显然此时在计数时会记重,所以我们忽略它,只考虑第二类。

我们注意到非法的字符读入数量是单调的:假设对于状态 \(S\) 有字符 \(p\) 非法,同时 \(S'\)\(S\) 转移得到,那么显然 \(p\) 对于 \(S'\) 同样非法,对于每个状态预处理有多少个接受字符是非法的,预处理可以走到终点的状态,问题变成给定一张 DAG,每条边有边权(每条边表示从状态 S 走到状态 S' 会增加多少个非法的元素),记 \(k\) 为当前经过的边权和,每次走过一条边之后累加 \(k\) (实质表示有 \(k\) 个元素),然后每次走过一条边之后可以以任意顺序删除若干个元素,求经过 \(\max\{S\}\) 条边同时用光边权的方案数。

\(f_{S,j}\) 表示当前到达状态 \(S\),剩余边权/元素数为 \(j\) 的方案数即可,转移可以直接 copy dp 数组然后再对内部进行转移,可以简单的做到 \(\mathcal O(2^n\cdot n^2)\),预期十分跑不满,所以感觉挺能过的,试了一下发现确实可以过。

然后我们可以优化到 \(\mathcal O(2^n\cdot n)\)

我们考虑将那个无用的维度 \((\text{指}j)\) 压掉,显然在转移某条边的时候,我们只需要保证先放入了 S 中的第一个元素,然后剩余的位置可以直接通过组合计数处理。

具体来说是设这条边上有 \(k\) 个元素,前面的元素我们都直接填入位置中,那么当前会剩余 \(n-|S|-f_S-1\),其中 \(f_S\) 表示非法的字符数量(我们考虑从 S 转移到其他状态),那么方案数就是 \(\binom{n-|S|-f_S-1}{k}\)

posted @ 2020-09-12 12:18  Soulist  阅读(252)  评论(0编辑  收藏  举报