给定一个字符串s,你可以从中删除一些字符,使得剩下的串是一个回文串。如何删除才能使得回文串最长呢?
输出需要删除的字符个数。
代码
1 |
|
算法
这道题可以看成是求解一个序列和此序列倒序列的最长公共子序列长度问题(LCS),解决此类方法的算法核心是动态规划算法
动态规划算法
序列A=(a1,a2,a3……an),序列B=(b1,b2,b3……bm),它们的LCS为序列C(c1,c2,c3……ck)1
2
3如果an=bm,则ck=an=bm,且ck-1是an-1和bm-1的LCS
如果an≠bm,则ck≠an,所以c是an-1和bm的LCS
如果an≠bm,则ck≠bm,所以c是bm-1和an的LCS
所以,用p(i,j)来表示序列长度1
2
3当n=0,或m=0,p(n,m)=0
当n,m≠0,且an=bm,p(n,m)=p(n-1,m-1)+1
当n,m≠0,且an≠bm,p(n,m)=max{p(n-1,m),p(n,m-1)}
对应上述的xuliechangdu函数
补充
当找到回文串时,需要把这个回文串打印出来,利用动态规划的逆想法,如上述的1
2void printzixulie(string a, int **f,int n,int m,string &re)
{}
通过对求取序列长度函数中的tag标号来判断当前下标的字符是否需要输出,同样利用递归的思想,逐个输出tag为1时相对应下标的字符。
注意
本文所述的算法仅适用于本题算法,动态规划问题可以求取两个不同字串的公共字符串长度,需要在本文的算法上稍作修改1
21.对于输入,需要输入两个不同的字符串
2.对于输出,由于公共子串不一定是回文,所以本文的输出是从后往前输出,需要注意反序