Question: Click to open the link
Theme
Returns the longest return string of a string. If multiple results exist, the minimum Lexicographic Order is output.
Ideas
We all know that we can calculate the maximum length of a string in the descending order of a string and the longest common subsequence of the original string.
However, this question should not only be output to the text string, but also be the smallest Lexicographic Order, so it is quite difficult.
Set str1 to a forward string and str2 to a reverse string.
F [I] [j]. len indicates the first I bit of str1, the first j bit of str2, and the longest length of the common substring.
F [I] [j]. str indicates the first I bit of str1, the first j bit of str2, and the minimum lexicographic string of the longest common substring.
Status transfer is similar to normal LCS, but it only adds the string with the minimum record Lexicographic Order
However, the final f [I] [j]. str is not necessarily the answer, because the longest common subsequence calculated is not necessarily a return string.
For example:
Kfclbckibbibjccbej
Jebccjbibbikcblcfk
Bcibbibc is their LCS, but it is not a reply string
However, the first len/two must be the first half of the input string.
After knowing the first len/2, you can directly construct the second half of the input string.
Note the parity of Length
Code
/** =================================================== ===== * This is a solution for ACM/ICPC problem ** @ source: uva-11404 Palindromic Subsequence * @ type: LCS minimum lexicographic return string * @ author: shuangde * @ blog: blog.csdn.net/shuangde800 * @ email: zengshuangde@gmail.com * =================================================== =====*/# include <iostream> # include <cstdio> # include <algorithm> # include <vector> # include <queue> # include <cmath> # include <cstring> # include <cstdlib> using namespace std; typedef long int64; const int INF = 0x3f3f3f3f; const int MAXN = 1010; char str1 [MAXN], str2 [MAXN]; int n, len; struct Node {int len; string str;} f [MAXN] [MAXN]; int main () {Node a, B; while (gets (str1 + 1 )) {// reverse len = strlen (str1 + 1); for (int I = 1; I <= len; ++ I) str2 [I] = str1 [len + 1-i]; // init for (int I = 0; I <= len; ++ I) f [0] [I]. len = 0, f [0] [I]. str = ""; // LCS for (int I = 1; I <= len; ++ I) {for (int j = 1; j <= len; ++ j) {if (str1 [I] = str2 [j]) {f [I] [j]. len = f [I-1] [J-1]. len + 1; f [I] [j]. str = f [I-1] [J-1]. str + str1 [I];} else {if (f [I-1] [j]. len> f [I] [J-1]. len) {f [I] [j]. len = f [I-1] [j]. len; f [I] [j]. str = f [I-1] [j]. str;} else if (f [I] [J-1]. len> f [I-1] [j]. len) {f [I] [j]. len = f [I] [J-1]. len; f [I] [j]. str = f [I] [J-1]. str;} else {f [I] [j]. len = f [I-1] [j]. len; f [I] [j]. str = min (f [I-1] [j]. str, f [I] [J-1]. str) ;}}} int maxx = f [len] [len]. len; string ans = f [len] [len]. str; // output if (maxx & 1) {for (int I = 0; I <maxx/2; ++ I) cout <ans [I]; for (int I = maxx/2; I> = 0; -- I) cout <ans [I]; putchar ('\ n ');} else {for (int I = 0; I <maxx/2; ++ I) cout <ans [I]; for (int I = maxx/2-1; I >= 0; -- I) cout <ans [I]; putchar ('\ n') ;}} return 0 ;}