jzoj4387 【GDOI2016模拟3.15】基因合成 (回文树上dp)

题面

这里写图片描述
n<=1e5

回文树的dp

首先最优解大概是先构出一个偶回文串,然后再将其他字符在首尾添加上。

考虑到操作2之后必定是偶回文串,我们可以先建出回文树,然后在上面dp.

对于奇回文串,我们可以不将他作为那个“较长的回文串”, 因为可以通过取他的一些子串来等价。

  • 我们想计算出构造出每一个偶回文串需要多少步数。

对于偶回文串,其他回文串要构出他,
首先要是他的子串吧, 这保证在回文树转移与fail链(父亲指向儿子)构出的dag中,子串可以到大串,这是一个结论。

设f[i]表示,最后一次操作是翻转,构出i这个偶回文串的最小代价。 (空串也默认翻转一次,方便下面转移)

我们实际上只要支持两种转移,就可以覆盖所有子串了:

对于转移祖先:
差了首尾两个字符。
由于其他偶回文串也是翻转来的, 我们可以假装改变一下操作顺序: 先加字符再翻转, 这样是1的代价。

对于fail链上的转移:
即是他的回文后缀,此时我们考虑翻转(强制要求最后一次操作是翻转),那么这个串的长度不能超过一半。这个位置与fail求法相同,稍微判断一下就可以了。

然后,将其补齐一半再翻转,算一下代价即可(这个翻转是要计算代价的)

代码写的太丑就不放了。

猜你喜欢

转载自blog.csdn.net/jokerwyt/article/details/81123952