AtCoder Beginner Contest 395
ABC395
Resources
Submission (A~E)
F Solution
如果只有第一个限制,那么求出 \(\min H_i\)(下文用 \(H_m\) 代替),将所有 \(H_i > H_m\) 的都修剪一下就好了。
如果只有第二个限制,可以用优先队列,将所有 \(U_i\) 扔到队列中,每次取出最短的牙齿(设其为 \(U_p\)),然后检查这个牙齿相邻的两个牙齿 \(U_{p-1}\) 和 \(U_{p+1}\),检查它们是否满足 \(U_{p-1}\le U_p + X\) 和 \(U_{p+1}\le U_{p} + X\)(显然 \(U_{p-1}, U_{p+1}>U_p\))。如果不满足,例如 \(U_{p-1} > U_p + X\),那么令 \(U_{p-1}\gets U_p + X\)。
可以证明这个修剪是必要的:因为不可能存在一种合法情况满足 \(U_{p-1}>U_p+X\),说明 \(U_{p-1}\) 一定要被修剪。
当然,更新完之后要把这些修剪后的牙齿塞回优先队列。显然,每个 \(U_i\) 最多只会被塞入队列 3 次(初始化、被左边的牙齿更新、被右边的牙齿更新)。时间复杂度是 \(O(n\log n)\)。至此,就解决完第二个限制了。
我们考虑在第二个限制的基础上加上第一个限制。假设所有牙齿已经被上述过程修剪过了(称为第一次修剪),我们得到了序列 \(\{U_{i}'\}\)。此时求出 \(H_i'\) 和 \(H_m'\)。可以证明,\(H_m'\) 就是题目所说的 \(H\)。证明如下:
如果 \(\forall i, U_i'\le H_m'\),那么我们只需要把 \(D_i\) 减少即可。
否则,存在一些位置 \(i\) 满足 \(U_i' > H_m'\),我们只需要把这些位置的牙齿修剪即可 \(U_{i}\gets H_m', D_i\gets 0\)(称为第二次修剪)。我们得到一个新的序列 \(\{U''_i\}\)
第二次修剪是否会破坏第二个限制呢?答案是不会的。
反证法。假设第二次修剪导致第二个限制被破坏了,即,存在某个 \(i\),在它被修剪后,它和相邻的牙齿高度差大于 \(X\)。
- \(U''_{i-1} > U''_i + X = H_m' + X\):不可能,因为第二次修剪后,所有 \(U_i''\) 都应该小于等于 \(H_m'\)。
- \(U_{i-1}'' < U_i'' - X = H_m' - X\):不可能,因为假设不等式成立,说明 \(i-1\) 没有在第二次修剪被剪掉,即 \(U'_{i-1} = U''_{i-1}\)。我们知道 \(U_{i}'' - U''_{i-1} > X\),则有 \(X < U_i'' - U_{i-1}'' = U_i'' - U_{i-1}' \le U_i' - U_{i-1}'\)。但我们知道第一次修剪后有 \(|U_i'-U_{i-1}'|\le X\),矛盾。
我们证明了第二次修剪保持了第二个限制的成立性,并且保证了第一个限制的成立,故此构造是合法的。
G Solution
还是考虑用最小斯坦纳树的算法。
此算法求出了 \(f(i, S)\) 表示以 \(i\) 为根,包含集合 \(S\) 内所有节点的最小斯坦纳树的代价。空间大小是 \(O(N2^K)\) 的
假设只有 \(1, 2, \cdots, K, s_i\),那么直接回答 \(f(s_i, [K])\) 即可,其中 \([K]\) 表示包含 \(1, 2, \cdots, K\) 的全集。问题在于本题是 \(1, 2,\cdots, K, s_i, t_i\)。
不难注意到 \(N\) 比较小(\(N\le 80\)),那么可以考虑一个更大的集合 \(U\):
二元组 \((S, k)\) 表示 \(S\) 集合和 \(k\) 号节点在最小斯坦纳树上,当 \(k\) 等于 \(0\) 时表示只有 \(S\) 在最小斯坦纳树上。可以发现这个集合的大小是 \(O(2^KN)\) 的。最后仍然使用 \(f(i, S)\) 设计 dp 状态,保证 \(S\in U\) 即可。状态空间的大小是 \(O(N^22^K)\) 的。回答的时候只需要回答 \(f(s_i, ([K], t_i))\)。
最后分析时间复杂度,大概是 \(O(N2^K\times N\log N + N^23^K)\) 的。
本文来自博客园,作者:lingfunny,转载请注明原文链接:https://www.cnblogs.com/lingfunny/p/18746494

浙公网安备 33010602011771号