直接套用这个递归的方法会部分用例超时。
参考评论区的题解可以高效解决:
  //dp[i][j]指字符串s在[i, j]范围内最长的回文子序列的长度。
  //在判断回文子串的题目中,关键逻辑就是看s[i]与s[j]是否相同。
  //如果s[i]与s[j]相同,那么dp[i][j] = dp[i + 1][j - 1] + 2;
  //如果s[i]与s[j]不相同,说明s[i]和s[j]的同时加入 并不能增加[i,j]区间回文子串的长度,那么分别加入s[i]、s[j]   看看哪一个可以组成最长的回文子序列。
  //加入s[j]的回文子序列长度为dp[i + 1][j]。
  //加入s[i]的回文子序列长度为dp[i][j - 1]
  //那么dp[i][j]一定是取最大的,即:dp[i][j] = max(dp[i + 1][j], dp[i][j - 1]);
#include<bits/stdc++.h>
using namespace std;
int main()
{
    string s;
    cin >> s;
    vector<vector<int> >dp(s.size(),vector<int>(s.size(),0));
  //dp[i][j]指字符串s在[i, j]范围内最长的回文子序列的长度。
  //在判断回文子串的题目中,关键逻辑就是看s[i]与s[j]是否相同。
  //如果s[i]与s[j]相同,那么dp[i][j] = dp[i + 1][j - 1] + 2;
  //如果s[i]与s[j]不相同,说明s[i]和s[j]的同时加入 并不能增加[i,j]区间回文子串的长度,那么分别加入s[i]、s[j]   看看哪一个可以组成最长的回文子序列。
  //加入s[j]的回文子序列长度为dp[i + 1][j]。
  //加入s[i]的回文子序列长度为dp[i][j - 1]
  //那么dp[i][j]一定是取最大的,即:dp[i][j] = max(dp[i + 1][j], dp[i][j - 1]);
    for(int i = 0;i<s.size();i++)dp[i][i] = 1;
    for(int i = s.size()-1;i >= 0;i-- )
    {
        for(int j = i+1;j < s.size();j++)
        {
            if(s[i] == s[j])dp[i][j] = dp[i+1][j-1] + 2;
            else dp[i][j] = max(dp[i][j-1],dp[i+1][j]);
        }
    }
    cout<<dp[0][s.size()-1];
    return 0;
}