ABC225F

题面

link

​ 有\(n\)个字符串,从中选出\(m\)个以任意顺序拼起来,求所有情况中字典序最小的。

题解

​ 首先考虑如果已经选出了\(m\)个字符串,我们应该按什么顺序拼起来。

​ 算是一个trick,重载小于号为\(S_1+S_2<S_2+S_1\)。(如果交换两个相邻的可以更优的话肯定交换)

​ 但是这个排序方式符合要求吗,会不会出现\(S_1<S_2,S_2<S_3\)\(S_3<S_1\)的情况呢。

​ 其实不会,你可以将长度相等的两个字符串的字典序比较想象成两个26进制的数比较大小,所以:

\[\begin{aligned} &S_1+S_2<S_2+S_1\\ \Leftrightarrow&S_1\times26^{|S_2|}+S_2<S_2\times26^{|S_1|}+S_1\\ \Leftrightarrow&\dfrac{S_1}{26^{|S_1|}-1}<\dfrac{S_2}{26^{|S_2|}-1} \end{aligned} \]

​ 最后你会发现其实排序依照的只有\(S_i\)自己的信息,并没有必须得两个字符串才会有意义。

​ 所以按这个方法给字符串排序之后,就可以进行DP看究竟选哪\(m\)个。

​ 方法有很多,但错误方法更多。大致原因都是因为字符串没有局部最优得整体最优,即如果\(S_1\)\(S_2\)的前缀,则\(S_1<S_2\)的,但可能出现\(S_1+x>S_2+x\)的情况,所以正确DP的核心就是去除这种前缀关系。

  • 方法一:从后往前DP,这样就保证了不会出现前缀的情况,而后缀情况因为后面不会再接新字符串了,所以可以保证最优。转移:

    \[f[i][j]=min(f[i+1][j],S_i+f[i+1][j-1]) \]

  • 方法二:将长度引入状态,在相同长度下,字典序最小一定更优,也去除了前缀带来的影响。

启发

  • 给多个字符串拼接最小字典序的排序方法。
  • 处理字符串字典序最小/最大的问题时,注意前缀的情况,以及通过反向DP去除影响。
posted @ 2022-02-17 17:28  qwq_123  阅读(20)  评论(0编辑  收藏  举报