UVA 11404 - Palindromic Subsequence
求给定字符串的最长回文子序列,长度一样的输出字典序最小的。
对于 [l, r] 区间的最长回文串。他可能是[l+1, r] 和[l, r-1]两个区间的结果。
或者当s[l] == s[r]时,区间[l+1, r-1]的结果再加上以s[l], s[r]为首尾的子序列。
dp存的是子序列,即一个string。
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; const int MAXN = 1000 + 5; string s; string dp[MAXN][MAXN]; void init() { for (int i=0; i<MAXN; i++) { for (int j=0; j<MAXN; j++) { dp[i][j] = "#"; } } } string DP(int l, int r) { if (dp[l][r] != "#") return dp[l][r]; if (l > r) return dp[l][r] = ""; if (l == r) return dp[l][r] = string(1, s[l]); string a, b, c, res; a = DP(l+1, r); b = DP(l, r-1); c = DP(l+1, r-1); if (a.size() < b.size()) res = b; else if (a.size() > b.size()) res = a; else if (a < b) res = a; else res = b; if (s[l] == s[r]) { c = string(1, s[l]) + c + string(1, s[r]); } if (res.size() == c.size()) { if (res > c) res = c; } else if (res.size() < c.size()) res = c; return dp[l][r] = res; } int main () { for (; cin >> s; ) { init(); string ans = DP(0, s.size()-1); cout << ans << endl; } return 0; }