'''
一、题目描述
问题较为简单，给定一个字符串，如"aasasbc"，计算出该字符串中最长的回文子序列长，即为"aaa"的长度3，回文子序列是指顺序和倒序均为同一个字符串的序列，另外，要求所输入的字符串长度不大于1000。
二、思路解析
分治算法去解决这道题是第一思路，即对于一个长度为n的字符串，对应于一个分治算法的状态数组dp[n-1][n-1]，该数组的值对应字符串中最长回文子序列的长度，
如dp[i][j]则代表着字符串中第i位到第j位的子序列中的最长回文子序列长度为dp[i][j]，明确这一点后，我们要作的即为求出dp[0][n-1]的值并输出即可。
利用分治算法的思想，当某子串s(i,j)中s[i]与s[j]相等时，那么其头尾两字符一定位于其最长回文子串中，因此该子串的最长回文子序列长度等于去掉头尾两字符后新子串的最长回文子序列长度加二，
我们可制定公式如下：dp[i][j] = dp[i + 1][j - 1] + 2。当s[i]与s[j]不相等时，则dp[i][j] = max(de[i + 1][j],dp[i][j - 1]）。有了这个规则，我们接下来只需要遍历出该字符串s的每一个子串，
即dp数组中的每一个值，最终输出dp[0][n-1]。
'''

class Solution:
    def longestPalindromeSubseq(self, s: str) -> int:
        ## 分治算法
        l = len(s)
        if s == s[::-1]:
            return l
        tmp = [[0 for j in range(l)] for i in range(l)]
        for j in range(l):
            tmp[j][j] = 1
            for i in range(j - 1, -1, -1):
                if s[i] == s[j]:
                    tmp[i][j] = 2 + tmp[i + 1][j - 1]
                else:
                    tmp[i][j] = max(tmp[i + 1][j], tmp[i][j - 1])
        return tmp[0][l - 1]