由于一个回文序列去掉头尾两个字符后的子序列依然仍是回文序列,从这点出发,我们可以认真考虑使用动态规划来解决这个问题。
依然进行按照动态规划问题的四个步骤解决问题。
其实按照个人理解,动态规划问题是一个有格外存储空间的循环问题,并且其每个步骤并不是相互割裂的,而是在问题或条件确定上都有着联系。
状态定义
假设我们采用dp[i]的一维数组表示遍历到s[i]时最长回文子序列时,再考虑到转移方程制定的时候,我们仅可以利用一次循环,一次只能有一个字符被遍历到,不符合回文序列中关于其子序列的定义,一次去掉头尾两个字符。
因此,利用二维数组dp[i][j]表示从字符s[i]到s[j]的最长回文子序列。0<=i<=j<n
转移方程
对于一个回文序列和其子序列的关系而言,明显看出dp[i][j]是和s[i],s[j]密切相关的。
s[i]和s[j]的关系是不被我们所知道的,分为两种情况:
1.s[i]==s[j],此时
dp[i][j]=dp[i+1][j-1]+2
2.s[i]!=s[j],此时
dp[i][j]=max(dp[i+1][j],dp[i][j-1])
初始条件
根据定义而言,0<=i<=j<n,而且dp[i][i]=1,单个符号的回文子序列为1。
最后结果
dp[0][s.size-1];
代码
像开头所提,动态规划问题是带有存储结构的循环问题,根据转移方程和初始条件判断出来,此题的循环是i从size-1的逆循环。