zoukankan      html  css  js  c++  java
  • agc026_e Synchronized Subsequence

    agc026_e Synchronized Subsequence

    https://atcoder.jp/contests/agc026/tasks/agc026_e

    https://img.atcoder.jp/agc026/editorial.pdf

    Snipaste_2020-03-02_18-59-52.png

    Tutorial

    定义a第 (i) 次出现的位置为 (a_i) ,b第 (i) 次出现的位置为 (b_i) .

    我们将字符串分为尽量多的部分,使得每一部分的a,b出现次数相同,这样的话,对于每个 (i) , (a_i)(b_i) 属于同一部分

    观察每一部分,发现分为两种情况

    • (forall i, a_i<b_i)
    • (forall i, a_i>b_i)

    首先假设整个串只有一部分.

    (forall i, a_i < b_i) 时:

    答案一定是形如ababab...的串,否则考虑答案中两个相邻的a,它形如(cdots a_ia_j cdots b_i cdots b_j) ,发现去掉 (a_j,b_j) 会更优.

    我们可以贪心的计算一共可以找到多少个ab,我们先选择 (a_1,b_1) ,然后找到第一个 (i) 满足 (a_i>b_1) ,如此迭代下去.

    (forall i ,a_i > b_i) 时:

    假设我们选择了 (a_i,b_i) 且未选择 (a_{i+1},b_{i+1}) ,那么我们总是可以通过选择 (a_{i+1},b_{i+1}) 来使答案更优( (cdots b_i cdots b_{i+1} cdots a_i cdots a_{i+1}) )

    所以最优的答案形如 (a_i,b_i,a_{i+1},b_{i+1},cdots) 的形式,我们枚举 (i) 即可算出最优的答案.

    那么如果有多个部分应该如何计算.

    我们首先对于每一部分算出最优解,然后对于每一部分,我们要么选择最优解,要么选择空串.因为当 (a_i>b_i) 时,所有我们可以得到的其他串不是最优串的前缀.

    发现选择一个串的条件是它大于等于之后的所有串拼起来时长度和它相同的前缀,可以在 (O(n^2)) 的时间统计答案.

  • 相关阅读:
    Brupsuite 中插件CO2的使用
    记事本默认编码改为UTF-8
    Crackme031
    Crackme030
    Crackme029
    Crackme028
    Crackme026
    Crackme025
    Crackme024
    Crackme022
  • 原文地址:https://www.cnblogs.com/ljzalc1022/p/13191026.html
Copyright © 2011-2022 走看看