ARC058F

首先用背包算出后 \(i\) 个字符串能拼成的长度。

考虑从前往后 dp 出每个长度的字典序最小的字符串。设 \(f_{i,j}\) 表示前 \(i\) 个字符串拼成的长度为 \(j\) 的字典序最小的字符串。显然 \(f_{i,j}\) 只有在 \(i+1\sim n\) 这些字符串能拼成长度为 \(k-j\) 的串时才有值。注意到对于两个合法的 \(j_1,j_2\) 满足 \(j_1<j_2\),且 \(f_{i,j_1}\) 不为 \(f_{i,j_2}\) 的前缀,那么他们两个中字典序较大那个一定没有机会成为答案。所以 \(f_i\) 一定形如一个母串,和他的一些前缀。考虑先用 dp 从 \(f_{i-1}\) 转移到 \(f_i\),有 \(f_{i,j}=\min(f_{i-1,j},f_{i-1,j-|s_i|}+s_i)\)。然后再将 \(f_{i,j}\) 按照 \(j\) 从小到大的顺序插入单调栈中。比较大小可以用 Z 函数,但是我写了二分哈希。只需要维护一下 \(f_{i-1}\) 的母串和每个 \(s_i\) 的前缀哈希值,以及 \(f_{i,j}\) 是从哪里转移过来的就可以实现。复杂度 \(O(nk\log k)\)

https://atcoder.jp/contests/arc058/submissions/40069207

posted @ 2023-04-13 22:54  CelticOIer  阅读(13)  评论(0编辑  收藏  举报