Codeforces Round #787 (Div. 3)
作者:互联网
A. Food for Animals
优先买前两种,再用第三种。
B. Make It Increasing
感觉自己写复杂了。
\(dp_{i, j}\)表示第\(i\)个元素使用\(j\)次操作的代价。
\[dp_{i + 1, k} = \left\{ \begin{aligned} &\min_j dp_{i, j} + k & f(a_i, j) < f(a_{i + 1}, k)\\ &\inf & else\\ \end{aligned} \right. \]其中\(f(x, y)\)表示对\(x\)用\(y\)次操作后的结果。
C. Detective Task
对于\(i\),如果前面没有0
且后面没有1
,那么\(i\)就是一个可行的解。
预处理一下前后缀就可以线性解决。
D. Vertical Paths
观察可得:路径数量等于叶子的数量。
枚举所有的叶子,对于每一个叶子,不断往父亲跳直到遇到已经经过的节点,每遇到一个节点就将其加入这个叶子对应的路径。
E. Replace With the Previous, Minimize
维护一个映射\(f(ch)\)表示字符串中所有的\(ch\)已经被替换为\(f(ch)\)。
然后从前往后枚举字符串中的字符,遇到一个不是a
的字符,就对其使用操作直到操作耗尽或者其变成a
。
由于只有26个字母,所以维护还是比较简单的。
F. Vlad and Unfinished Business
首先,考虑\(x = y\)的情况,这是一个经典的问题。从\(x\)开始DFS,对于边\(u \rightarrow v\),如果以\(v\)为根的子树包含需要去的节点,那么边\(u \rightarrow v\)对答案有\(2\)的贡献(最优的情况下会经过这条边两次,递归和回溯各一次)。假设这种情况的答案为\(sum\),跑遍DFS就可以算出来。
考虑\(x = y\)不一定成立的情况。假设已经经过了所有需要去得节点,且所有需要去的节点中最后一个去的是\(z\),并且现在停在\(z\)。此时耗费的代价为\(sum - dep_z\),其中\(dep_i\)表示节点\(i\)的深度。现在只需要再从\(z\)走到\(y\)就可以了,代价为\(z\)到\(y\)的最短路,这个借助LCA就可以\(O(n\log n) \sim O(\log n)\)。这里我用的树剖算LCA。
由于计算是\(O(\log n)\)的,\(z\)的可能取值有\(O(n)\)种,直接枚举所有要去的节点即可。
总的时间复杂度是\(O(n \log n)\),瓶颈在于LCA的计算。
G. Sorting Pancakes
TBA。
写在最后
下班的时候就只剩1h了,F结束后几分钟过的,G还没时间看。
标签:787,log,Codeforces,枚举,ch,LCA,Div,节点,dp 来源: https://www.cnblogs.com/zengzk/p/16227126.html