此题真心有难度,之前刷紫书dp题时就卡在这题,重新拿起总算基本想通,但是关于每个串都与下个串有重叠的解决办法没有看懂,最后去看了下LRJ的代码,原来根本不必额外特判什么的。只需要规定一个串为首串,在最后的时候把dp[(1<<n)-1][x]中的x与规定那个串减下重叠长度就行,至于绕好几圈的那个问题就更加简单了,因为如果他绕了好几圈,那么在去除那些被包含的串的时候,就会把所有的串除了那个绕几圈的串给删除,最后只剩下那个绕几圈的串,那么在做预处理2个串(自己和自己)最大叠起来长度的时候,就已经找到这个串的最短长度了,最短长度等于串长度减去重叠的就是了,这个和kmp里的一道题的思想类似。
然后其他的做法书上都说了,对于一个状态加一个串是正过来贴还是反过来贴去更新下个状态。
然后我还犯了一个很隐蔽的错误,找了很久。。具体就是,在去除那些被包含的串的时候,如果2个串是相同或者是颠倒相同的时候,我会把2个串都删了。。这个LRJ代码里是按照长度排序后只跟后面的一一比较。而我是全部都比较,所以会出现这个问题,解决的话规定一个方向就行了,如果是2个串长度一样,且重叠起点是开头,那么i>j才删除,反之不删除。
其实现在想想,此题的难度就在于圈的时候怎么处理,以及预处理写起来比较烦。
AC代码: