Codeforces-17C Balance

拟墨画扇 提交于 2019-12-02 19:59:08

题目大意:

  给定一个长度为n的只含有a,b,c的字符串,对该字符串进行多次(或0次)以下操作:将某个位置的字符变为其左边的或右边的。求操作后所得字符串满足3种字符两两数量差不超过1的有多少个?

  n<=150

题目解法:

  观察原始字符串A和变化字符串B的关系。

  可以发现(赫赫 窝就无法发现)若我们将A和B均进行去重操作分别得到A' B',那么B'一定是A'的子串。它的正确性也是比较显然的(emm某个字符若想跑到前面的字符前面那么一定会将前面的字符覆盖(((

  那么我们就可以将原串直接去重得到S,然后我们只需要一位一位生成新串与原串匹配即可。f[i][a][b][c]表示匹配到原串的第i位,有a个'a',b个'b',c个'c'的字符串个数,根据下一位字符的三种选择,它可以向后转移到f[nxt[i]['a']][a+1][b][c], f[nxt[i]['b'][a][b+1][c], f[nxt[i]['c'][a][b][c+1]。其中nxt数组时需要预处理,表示第i位后第一个a/b/c的位置。因为ab和abbb去重后相同显然是可以匹配到相同位置的,因此这里的nxt定义中的下一个包含其本身。

  答案统计只需要在计算过程中将满足a+b+c==n且差值不大于1的f值累加起来即可。看似是O(n^4)的复杂度,实际上后面三维大概在n/3的大小(不然某一个字符过多显然无法满足差值上的要求),所以可以在150*50^3内完成,时间复杂度不成问题。

  

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!