UVa 11404 - Palindromic Subsequence (最长回文子序列 DP)
2014-07-28 21:16
399 查看
Palindromic Subsequence
[Submit] [Go Back] [Status]
Description
A Subsequence is a sequence obtained by deleting zero or more characters in a string. A Palindrome is a string which when read from left to right, reads same as when read from right to left. Given a string, find the longest palindromic subsequence. If there
are many answers to it, print the one that comes lexicographically earliest.
Constraints
Maximum length of string is 1000.
Each string has characters `a' to `z' only.
Input
Input consists of several strings, each in a separate line. Input is terminated byEOF.
Output
For each line in the input, print the output in a single line.
Sample Input
Sample Output
题意:
给定一个由小写字母组成的字符串,删除其中的0个或多个字符,使得剩下的(顺序不变)组成一个尽量长的回文串。如果有多解,输出字典序最小的。
思路:
可以转化为LCS问题,就是该字符串与它逆序串的LCS
但是求出来的LCS不一定是回文串,比如:
kfclbckibbibjccbej
LCS : bcibbibc
结果应该是:bcibbicb
因此由它前len/2可得到回文串
第二种见下面
因为长度num 定义为了char,导致无限WA
再贴上另外一种思路:
Time Limit:3000MS | Memory Limit:Unknown | 64bit IO Format:%lld & %llu |
Description
A Subsequence is a sequence obtained by deleting zero or more characters in a string. A Palindrome is a string which when read from left to right, reads same as when read from right to left. Given a string, find the longest palindromic subsequence. If there
are many answers to it, print the one that comes lexicographically earliest.
Constraints
Maximum length of string is 1000.
Each string has characters `a' to `z' only.
Input
Input consists of several strings, each in a separate line. Input is terminated byEOF.
Output
For each line in the input, print the output in a single line.
Sample Input
aabbaabb computer abzla samhita
Sample Output
aabbaa c aba aha
题意:
给定一个由小写字母组成的字符串,删除其中的0个或多个字符,使得剩下的(顺序不变)组成一个尽量长的回文串。如果有多解,输出字典序最小的。
思路:
可以转化为LCS问题,就是该字符串与它逆序串的LCS
但是求出来的LCS不一定是回文串,比如:
kfclbckibbibjccbej
LCS : bcibbibc
结果应该是:bcibbicb
因此由它前len/2可得到回文串
第二种见下面
因为长度num 定义为了char,导致无限WA
#include <cstdio> #include <iostream> #include <vector> #include <algorithm> #include <cstring> #include <string> #include <map> #include <cmath> #include <queue> #include <set> using namespace std; //#define WIN #ifdef WIN typedef __int64 LL; #define iform "%I64d" #define oform "%I64d\n" #define oform1 "%I64d" #else typedef long long LL; #define iform "%lld" #define oform "%lld\n" #define oform1 "%lld" #endif #define S64I(a) scanf(iform, &(a)) #define P64I(a) printf(oform, (a)) #define P64I1(a) printf(oform1, (a)) #define REP(i, n) for(int (i)=0; (i)<n; (i)++) #define REP1(i, n) for(int (i)=1; (i)<=(n); (i)++) #define FOR(i, s, t) for(int (i)=(s); (i)<=(t); (i)++) const int INF = 0x3f3f3f3f; const double eps = 10e-9; const double PI = (4.0*atan(1.0)); const int maxn = 1000 + 20; char s1[maxn]; char s2[maxn]; int dp[maxn][maxn]; string ansA[maxn][maxn]; int n; void LCS() { for(int i=0; i<=n; i++) { dp[0][i] = 0; ansA[0][i] = ""; } for(int i=1; i<=n; i++) { for(int j=1; j<=n; j++) { dp[i][j] = 0; ansA[i][j] = ""; if(s1[i] == s2[j]) { dp[i][j] = dp[i-1][j-1] + 2; ansA[i][j] = ansA[i-1][j-1] + s1[i]; } if(dp[i-1][j] > dp[i][j] || (dp[i-1][j] == dp[i][j] && ansA[i-1][j] < ansA[i][j])) { dp[i][j] = dp[i-1][j]; ansA[i][j] = ansA[i-1][j]; } if(dp[i][j-1] > dp[i][j] || (dp[i][j-1] == dp[i][j] && ansA[i][j-1] < ansA[i][j])) { dp[i][j] = dp[i][j-1]; ansA[i][j] = ansA[i][j-1]; } } } } char ans[maxn]; int main() { while(scanf("%s", s1+1) != EOF) { n = strlen(s1+1); for(int i=1; i<=n; i++) s2[i] = s1[n-i+1]; s2[n+1] = '\0'; LCS(); string aans = ansA ; strcpy(ans, aans.c_str()); int num = strlen(ans); for(int i=0; i<num/2; i++) { ans[num-i-1] = ans[i]; } puts(ans); } return 0; }
再贴上另外一种思路:
#include <cstdio> #include <iostream> #include <vector> #include <algorithm> #include <cstring> #include <string> #include <map> #include <cmath> #include <queue> #include <set> using namespace std; //#define WIN #ifdef WIN typedef __int64 LL; #define iform "%I64d" #define oform "%I64d\n" #define oform1 "%I64d" #else typedef long long LL; #define iform "%lld" #define oform "%lld\n" #define oform1 "%lld" #endif #define S64I(a) scanf(iform, &(a)) #define P64I(a) printf(oform, (a)) #define P64I1(a) printf(oform1, (a)) #define REP(i, n) for(int (i)=0; (i)<n; (i)++) #define REP1(i, n) for(int (i)=1; (i)<=(n); (i)++) #define FOR(i, s, t) for(int (i)=(s); (i)<=(t); (i)++) const int INF = 0x3f3f3f3f; const double eps = 10e-9; const double PI = (4.0*atan(1.0)); const int maxn = 1000 + 20; char str[maxn]; int dp[maxn][maxn]; string ansA[maxn][maxn]; int f(int st, int ed) { if(ed < st) return 0; if(st == ed) { ansA[st][ed] = str[st]; return 1; } if(dp[st][ed] != -1) return dp[st][ed]; int ret = 0; string rets = ""; if(str[st] == str[ed]) { ret = f(st+1, ed-1) + 2; rets = str[st] + ansA[st+1][ed-1] + str[ed]; } int t = f(st+1, ed); if(t > ret || (t == ret && ansA[st+1][ed] < rets)) { ret = t; rets = ansA[st+1][ed]; } t = f(st, ed-1); if(t > ret || (t == ret && ansA[st][ed-1] < rets)) { ret = t; rets = ansA[st][ed-1]; } ansA[st][ed] = rets; return dp[st][ed] = ret; } int main() { while(scanf("%s", str) != EOF) { int n = strlen(str); memset(dp, -1, sizeof(dp)); int ans = f(0, n-1); puts(ansA[0][n-1].c_str()); } return 0; }
相关文章推荐
- UVA - 11404 Palindromic Subsequence (最长回文子序列)
- UVa 11404 回文子序列(LCS求最长回文串长度)
- Stacking Boxes +uva+dp(最长严格降子序列的变形)
- UVA 11151 Longest Palindrome(最长回文子序列 + dp + LCS)
- HDU 4745 Two Rabbits ★(最长回文子序列:区间DP)
- hdu4745 最长回文子序列(区间DP)
- HDU 4745 Two Rabbits ★(最长回文子序列:区间DP)
- UVA 11404 Plalidromic Subsquence (回文子序列,LCS)
- HDU 4745 Two Rabbits【非连续最长回文子序列,区间DP】
- UVa 103 Stacking Boxes 堆砌盒子(DP 最长条件子序列)
- UVa 10534 Wavio Sequence (最长递增子序列 DP 二分)
- HDU 4745 (区间dp ,最长非连续回文子序列)
- 第13届景驰-埃森哲杯广东工业大学ACM程序设计大赛 D psd面试(最长回文子序列,区间dp)
- Is Bigger Smarter?+uva+简单dp(最长公共升降子序列的变形)
- hdu 4745 Two Rabbits(dp最长回文子序列)
- Vacation+uva+简单dp(最长公共升子序列)
- UVa 437 The Tower of Babylon(DP 最长条件子序列)
- UVa 10051 Tower of Cubes(DP 最长序列)
- uva 10131 Is Bigger Smarter ? (简单dp 最长上升子序列变形 路径输出)
- UVa 10534 Wavio Sequence (最长递增子序列 DP 二分)