强化反复

概述

  • 强化反复是一种随机化思想。

  • 具体来讲,有时题目中的限制过于复杂,无法处理或处理的复杂度不可接受。

  • 此时可以考虑通过随机化地加强限制获得一个较可做的条件,然后多次反复,只要有一次恰好是答案就算成功。

  • 注意,这种“加强限制”指的是将原限制简化规约到某个较强的限制上,必须保证对于所有弱限制下的可能解,都有随机化范围内占比足够大的强限制能构造出它,而非卡掉了。

例题

佛怒火莲

  • 题意:

    • 给定 \(n\) 个物品,每个物品有 \(v,c\) 两个参数。

    • 要求从中选出任意个,使得选出的物品集中至少有 \(k\) 种不同的 \(c\)

    • 对于一个选了 \(m\) 个物品的方案,它的权重是将选出的物品按 \(v\) 升序排序后的 \(\min_{i=1}^{m-1}(v_{i+1}-v_i)\)

    • 求最大可能权重。

  • 数据范围:

    • \(T\leqslant 5,n\leqslant 10^4\)

    • \(c_i\leqslant n,v_i\leqslant 10^6\)

    • \(k\leqslant 5\)

    • \(3s\) 时限。

  • 显然,同种颜色的物品最多取一个。于是想到状压,但状压 \(2^n\) 显然是自寻死路。

  • 先考虑压得下的话怎么办。发现没法记录上一个选的 \(v\) 和目前的 \(ans\)。于是想到二分答案 check,将物品按照 \(v\) 排序,状态转移方程中判一下 \(v\) 的差够不够大即可。

  • 即:

    • 状态设计:\(dp_{i,sta}\) 表示考虑了前 \(i\) 个物品,选了第 \(i\) 个物品,当前已选的物品颜色为 \(sta\),是否可行。

    • 初始化:\(dp_{0,0}=1\)

    • 状态转移方程:\(dp_{i,sta}=tp_{i-1,sta}|tp_{j,sta\oplus 2^{c_i}}(v_i-v_j\geqslant now)\),其中 \(now\) 为二分的答案,\(tp\)\(dp\) 的前缀或(也可认为是不要求必选 \(i\) 的伴生 DP 状态),理由显然。

  • 然而这个 \(sta\to 2^n\)。注意到 \(k=5\)。如果 \(sta=2^5\) 该多好啊。

  • 考虑染色!构建一个 \(f(c)=c'\) 的满射,\(c'\in[1,5]\)。如果最优解所需的五个物品恰好被染为了不同的颜色,则我们能 DP 出最优解。

  • 则染对色的概率为 \(\dfrac{5!}{5^5}=0.0384\)。设法多染几次就好了。

  • 原题后来的实现是把第二维 \(sta\) 压进 bitsetint 的每一位,从而复杂度为 \(O(T\times times\times n\log \frac{v}{4})\)\(times\) 为随机染色次数,可以看到 \(times\approx 333\),从而正确率 \(\geqslant 99.99\%\)

CF1310D Tourism

  • 题意:\(n\)\(m\) 边有边权有向图,无自环重边,求一个含 \(1\) 的恰有 \(K\) 条边的最小环,且环上不存在任意奇环。

  • 数据范围:\(n\leqslant 80,K\leqslant 10,3s\) 时限。

  • 不存在奇环很难整的。我会染色!

  • 将原图随机赋黑白色。不妨钦定 \(1\) 为白色,则还有至多 \(k-1\) 个点,染对色的概率为 \(\dfrac{1}{2^{k-1}}\)。染完之后直接跑 Bellman-Ford,只许走交替颜色,复杂度 \(O(n^2\times k)\),正确率 \(99.98\%\)

HDU6664

  • 题意:给定一张 \(n\)\(m\) 边带边权无向图,求包括 \(k\) 个点的最长(简单)路径长度。路径起点任选。

  • 数据范围:

    • \(T\leqslant 35\)

    • \(n,m\leqslant 10^4\)

    • \(2 \leqslant k\leqslant 6\)

    • \(\max(n,m)\geqslant 100\) 的测试点不超过 \(5\) 个。

  • 我会染色...考虑染六色,然后规定从 \(1\) 出发走到 \(6\),跑全源最长路跑六步?额好像不用,每条边肯定对应一种颜色转换,\(O(m)\) 就可以。

  • \(O(T\times times\times m)\)。单轮正确率下界为 \(\dfrac{1}{6^6}\)

  • 不行,有点低,全放 \(m=100\)\(times=6^6\) 就要 \(1.6\times 10^8\) 了,此时还有 \(35\%\) 的错误率。

  • 换个思路跑状压:

    • 状态设计:\(dp_{i,sta}\) 表示当前在 \(i\),已经有 \(sta\) 的颜色的最大路径长度。嗯显然可以分层转移(加一个走了几步),空间开销打一点但是常数小一点。

    • 初始化:\(dp_{i,2^{c_i}}=0\)

    • 递推转移:\(dp_{i,sta}\to dp_{j,sta|2^{c_j}}(sta\And 2^{c_j}=0)\),转移系数为 \(e_{i,j}\)

  • 正确率上升到 \(\dfrac{6!}{6^6}\),单轮复杂度上升到 \(O(n\times k\times sta)\)。算下来 \(times=74\),仍有 \(31\%\) 的错误率...不可做吗?

  • 错了,没有那个 \(k\) 的复杂度!没有外层枚举 \(k\) 的必要,直接从小往大枚举 \(sta\),一定没有后效性,不信可以连边 toposort 试试。于是复杂度实际上是 \(O(m\times sta)\)

  • 于是将小数据转化成大数据,估算得 \(times=20\),寄了啊。

  • 啊其实这个时候我们可以考虑调大 \(times\)。上面那个 DP 的复杂度分析是溢出的,实践中 \(times\)\(+100\),错误率降低一个数量级。

  • 为什么调大不会 T?本题 \(15s\) 时限。(来人,把这个不看题的给我叉出去!)

posted @ 2023-01-15 10:20  未欣  阅读(8)  评论(0编辑  收藏  举报