📅  最后修改于: 2023-12-03 15:23:02.614000             🧑  作者: Mango
给定一个字符串 S,求出S中最长回文子序列的长度。
输出一个整数,表示字符串 S 的最长回文子序列的长度。
10
BBABCBCAB
7
本题可采用动态规划的思路。
设 $dp[i][j]$ 表示字符串 $S$ 的第 $i$ 到第 $j$ 个字符组成的子串中,最长回文子序列的长度。
当 $i=j$ 时,$dp[i][i]=1$。
当 $i<j$ 时,若 $S_i=S_j$,则 $dp[i][j]=dp[i+1][j-1]+2$;否则,$dp[i][j]=\max{dp[i+1][j],dp[i][j-1]}$。
因此,我们可以先按照字符串的长度从小到大依次求出所有长度的回文子序列,最终得到整个字符串的最长回文子序列。
def lps(s: str) -> int:
n = len(s)
dp = [[0] * n for _ in range(n)]
for i in range(n):
dp[i][i] = 1
for l in range(2, n + 1):
for i in range(n - l + 1):
j = i + l - 1
if s[i] == s[j]:
dp[i][j] = dp[i + 1][j - 1] + 2
else:
dp[i][j] = max(dp[i + 1][j], dp[i][j - 1])
return dp[0][n - 1]
if __name__ == '__main__':
n = int(input().strip())
s = input().strip()
print(lps(s))
其中,lps(s: str) -> int
函数实现了回文子序列的长度计算。
dp[i][j]
表示字符串 $S$ 的第 $i$ 到第 $j$ 个字符组成的子串中,最长回文子序列的长度。
状态转移方程为:
最终,返回 $dp[0][n-1]$ 即可。