首先用背包算出后 \(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
标签:拼成,最小,ARC058F,字符串,长度,字典 From: https://www.cnblogs.com/CelticBlog/p/17316887.html