Erase First or Second Letter

先来看一下官方解答

首先对任意一个操作序列,如果存在某次操作二排在相邻的操作一前面,那我们把这两次操作换成连续的两次操作一,得到的字符串显然不变

所以我们可以先一直进行操作一,然后在进行操作二,我们把一种操作序列记为\((i,j)\),表示进行了\(i\)次操作一之后进行了\(j\)次操作二

我们接下来考虑什么时候两个字符串是一模一样的

所以显然有\(i_1+j_1=i_2+j_2\),因为要删掉同样多的字符;还有\(s_{i_1+1}=s_{i_2+1}\)

而在满足上面两个条件之后,我们惊奇地发现,这居然也是充分的(也就是此时字符串一定相同了)

所以我们有了下面这么一个算法:我们找出\(26\)个字符每一个字符第一次出现的位置(因为某个位置如果不是第一次出现的位置,那么从这个位置开始的任何一种操作序列,都可以转化成第一次出现的位置开始的某种操作序列),表示\(i\)的大小,而后面\(j\)无论为多少,显然最后得到的序列都不同

这题目的官解也提示我们,遇到这种操作序列的题目(放在比较前面的),可以考虑不同操作序列的等效性

然后说一下我的做法

我们观察一下样例,第一步操作无论是操作一还是操作二,会得到长度为\(n-1\)的字符串,而后面的\(n-2\)个字符一定是不变的;用数学归纳法可以得出,当我们删除\(i\)个字符后,无论我们的操作序列是什么,我们得到的最终长度为\(n-i\)的字符串,后面\(n-i-1\)个字符一定是相等的,所以我们只用考虑前面\(i+1\)个字符保留哪一个就好了

update 2024.7.10

重新做了一遍,居然按照官方的做法做出来了。。。

其实想出来也不是很难,操作序列的等效性也是常用trick,然后就要去找什么时候两个字符串是相同的,显然要先长度相同,也就是最后一截尾巴要一样长,然后再在前面去选一个字符作为开头,这样也很easy

posted @ 2024-02-24 13:47  最爱丁珰  阅读(11)  评论(0编辑  收藏  举报