直接套用这个递归的方法会部分用例超时。
参考评论区的题解可以高效解决:
//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; }