Sofia and Strings

看这篇题解

不可逆指的是一旦操作了,就没办法回到原来的序列了,所以根据决策包容性,尽量到后面再操作

我们先来考虑一下最终的对应至少满足什么条件

假设我们现在已经获得了一个ts的单射且这个单射可以通过排序变成t,我们依次考虑每一个t的字符

对于t1,我们假设其对应si1,那么对于s[1...i11],比t1小的字符一定是都会被删除的(否则t1不可能排到第一位)

我们对每个tj都考虑上述过程,当t[1...j1]都被考虑之后,我们来考虑tj,假设其对应sij,对于s[1...ij1]的字符,如果没被删除且没有被t[1...j1]选择且小于tj,那么我们就将其删除。注意对于每个tj我们对应的sij一定是没有被删除的,用反证法很容易证明

所以任意一个合法的单射一定可以通过上述测试

那我们再来考虑找一个匹配,先只考虑有删除操作(也就是说我们要按照某种方式找一个ts的单射,有可能可以通过排序来变成t,而且如果按照这种方式,单射不存在那么无论按照什么方式来找单射,单射肯定都不会存在)

对于t的第一个字符t1,他在s中有若干对应,分别是si1,si2,...(i1<i2<...),我们假设在最终方案中选一个sip,对于s[1...ip1],比sip小的字符是一定要删除的(否则t1不可能排在第一位,这个单射就不可能通过排序来变成t了);如果我们不选择si1,那么我们就会删除更多的数(比如选择si2,首先对于选择si1的时候,要删除的数肯定还是要删除,然后现在还多了一些介于i1i2之间数可能要被删除),于是如果存在合法的方案,我们在这个方案中,将选择si2变成选择si1一定是合法的,因为我们继续接下来的操作,如果某次操作会因为介于i1i2之间数没有被删除而无法进行的话,我们这个时候在删除就好了,这也是决策包容性的一种体现

利用数学归纳法,我们可以得出一种方案,假设对于t[1...i1]我们已经选择了最佳的方案,那么对于ti,我们首先找到其在剩下的s中的第一个位置sp,然后对于s[1...p1]的还没有被删除且没有被t[1...i1]选择的字符,如果其小于ti,那么我们就删除掉。经过以上的过程,这一定是必要条件,也就是说如果上面的过程中途出现了不合法,找不到单射,那么就一定不会有单射存在了

那么对于我们找到的这个单射,我们也可以通过排序将其变成合法的序列。我们只需要在ti对应的过程中,删除完前面该删除的字符之后,通过类似冒泡排序的邻项交换将其交换到ti1后面一位就好了

posted @   最爱丁珰  阅读(4)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
点击右上角即可分享
微信分享提示