LPS UVA 11404 Palindromic Subsequence

题目传送门

 1 /*
 2     LPS(Longest Palidromic Subsequence):最长回文子序列,和回文串不同,子序列是可以不连续的。
 3         转化为LCS问题,将字符串逆序,然后和本串求LCS就是LPS的长度(为啥不就是LPS?),但是前一半是LPS的一半,可以补全
 4         推荐->还有一种写法是用了LCS的思想,dp[i][j]表示i到j的最长回文串长度,状态转移方程:
 5             1. dp[j][j+i-1] = dp[j+1][j+i-2] + 2;   (str[j] == str[j+i-1])
 6             2. dp[j][j+i-1] = max (dp[j+1][j+i-1], dp[j][j+i-2]);   (str[j] != str[j+i-1])
 7 */
 8 /************************************************
 9  * Author        :Running_Time
10  * Created Time  :2015-8-7 14:26:22
11  * File Name     :UVA_11404.cpp
12  ************************************************/
13
14 #include <cstdio>
15 #include <algorithm>
16 #include <iostream>
17 #include <sstream>
18 #include <cstring>
19 #include <cmath>
20 #include <string>
21 #include <vector>
22 #include <queue>
23 #include <deque>
24 #include <stack>
25 #include <list>
26 #include <map>
27 #include <set>
28 #include <bitset>
29 #include <cstdlib>
30 #include <ctime>
31 using namespace std;
32
33 #define lson l, mid, rt << 1
34 #define rson mid + 1, r, rt << 1 | 1
35 typedef long long ll;
36 const int MAXN = 1e3 + 10;
37 const int INF = 0x3f3f3f3f;
38 const int MOD = 1e9 + 7;
39 string ans[MAXN][MAXN];
40 int dp[MAXN][MAXN];
41 char str[MAXN];
42
43 int main(void)    {     //UVA 11404 Palindromic Subsequence
44     while (scanf ("%s", str + 1) == 1)  {
45         int len = strlen (str + 1);
46         memset (dp, 0, sizeof (dp));
47         for (int i=1; i<=len; ++i)  dp[i][i] = 1;
48         for (int i=1; i<=len; ++i)  ans[i][i] = str[i];
49
50         for (int i=2; i<=len; ++i)   {      //区间长度
51             for (int j=1; j+i-1<=len; ++j)  {       //[j, j+i-1]
52                 if (str[j] == str[j+i-1])   {
53                     if (i == 2) {
54                         dp[j][j+i-1] = 2;
55                         ans[j][j+i-1] = ans[j][j] + ans[j+i-1][j+i-1];  continue;
56                     }
57                     dp[j][j+i-1] = dp[j+1][j+i-2] + 2;
58                     ans[j][j+i-1] = str[j] + ans[j+1][j+i-2] + str[j+i-1];
59                 }
60                 else if (dp[j+1][j+i-1] > dp[j][j+i-2]) {
61                     dp[j][j+i-1] = dp[j+1][j+i-1];
62                     ans[j][j+i-1] = ans[j+1][j+i-1];
63                 }
64                 else if (dp[j][j+i-2] > dp[j+1][j+i-1]) {
65                     dp[j][j+i-1] = dp[j][j+i-2];
66                     ans[j][j+i-1] = ans[j][j+i-2];
67                 }
68                 else    {
69                     dp[j][j+i-1] = dp[j+1][j+i-1];
70                     ans[j][j+i-1] = min (ans[j+1][j+i-1], ans[j][j+i-2]);
71                 }
72             }
73         }
74         int mlen = dp[1][len];
75         for (int i=0; i<mlen; ++i)  {
76             printf ("%c", ans[1][len][i]);
77         }
78         puts ("");
79     }
80
81     return 0;
82 }

 1 /************************************************
 2 * Author        :Running_Time
 3 * Created Time  :2015-8-7 14:26:22
 4 * File Name     :UVA_11404.cpp
 5  ************************************************/
 6
 7 #include <cstdio>
 8 #include <algorithm>
 9 #include <iostream>
10 #include <sstream>
11 #include <cstring>
12 #include <cmath>
13 #include <string>
14 #include <vector>
15 #include <queue>
16 #include <deque>
17 #include <stack>
18 #include <list>
19 #include <map>
20 #include <set>
21 #include <bitset>
22 #include <cstdlib>
23 #include <ctime>
24 using namespace std;
25
26 #define lson l, mid, rt << 1
27 #define rson mid + 1, r, rt << 1 | 1
28 typedef long long ll;
29 const int MAXN = 1e3 + 10;
30 const int INF = 0x3f3f3f3f;
31 const int MOD = 1e9 + 7;
32 struct Ans  {
33     int len;
34     string s;
35 }dp[MAXN][MAXN];
36 char str[MAXN], rstr[MAXN];
37
38 int main(void)    {
39     while (scanf ("%s", str + 1) == 1)  {
40         int len = strlen (str + 1);
41         for (int i=1; i<=len; ++i)  {
42             rstr[len-i+1] = str[i];
43         }
44         for (int i=0; i<=len; ++i)  {
45             dp[0][i].len = 0, dp[0][i].s = "";
46         }
47         for (int i=1; i<=len; ++i)  {
48             for (int j=1; j<=len; ++j)  {
49                 if (str[i] == rstr[j])  {
50                     dp[i][j].len = dp[i-1][j-1].len + 1;
51                     dp[i][j].s = dp[i-1][j-1].s + str[i];
52                 }
53                 else if (dp[i][j-1].len > dp[i-1][j].len)   {
54                     dp[i][j].len = dp[i][j-1].len;
55                     dp[i][j].s = dp[i][j-1].s;
56                 }
57                 else if (dp[i-1][j].len > dp[i][j-1].len)   {
58                     dp[i][j].len = dp[i-1][j].len;
59                     dp[i][j].s = dp[i-1][j].s;
60                 }
61                 else    {
62                     dp[i][j].len = dp[i-1][j].len;
63                     dp[i][j].s = min (dp[i-1][j].s, dp[i][j-1].s);
64                 }
65             }
66         }
67         int mlen = dp[len][len].len;
68         string ans = dp[len][len].s;
69         for (int i=0; i<mlen/2; ++i)  printf ("%c", ans[i]);
70         int j;
71         if (mlen & 1)   j = mlen / 2;
72         else    j = mlen / 2 - 1;
73         for (; j>=0; --j)   printf ("%c", ans[j]);
74         puts ("");
75     }
76
77     return 0;
78 }

LCS

时间: 2024-10-13 01:17:22

LPS UVA 11404 Palindromic Subsequence的相关文章

UVA 11404 Palindromic Subsequence[DP LCS 打印]

UVA - 11404 Palindromic Subsequence 题意:一个字符串,删去0个或多个字符,输出字典序最小且最长的回文字符串 不要求路径区间DP都可以做 然而要字典序最小 倒过来求LCS,转移同时维护f[i][j].s为当前状态字典序最小最优解 f[n][n].s的前半部分一定是回文串的前半部分(想想就行了) 当s的长度为奇时要多输出一个(因为这样长度+1,并且字典序保证最小(如axyzb  bzyxa,就是axb)) // // main.cpp // uva11404 //

UVA 11404 Palindromic Subsequence

题解: 神一般的trick 首先求最长回文字符串的长度.只用反过来.转换为LCS问题就行 但是关键的要输出字典序最小的 所以在LCS的过程中.保存相应的字符串,并且保证字符串最小.这么求得的长度是对的.但是不一定是回文字符串 例如 bcbabccb bccbabcb ---> bcabc. 想了很久.可能是因为字典序的问题.当前面一半固定的时候,后面一半应该是前面一半的翻转过来,但是有可能出现和前面一半一样的情景.....(有毒) 具体修改.就是取前面一半即可 代码: #include<bit

【UVa】Palindromic Subsequence(dp+字典序)

http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=465&page=show_problem&problem=2399 最长的很简单,将串翻转过来后求两个串的lcs就是答案.. 主要是字典序那里... 还是开string来比较吧.. 注意最后输出方案时用前半段推出后半段.(因为可能lcs时会重合...) #include <cstdio> #include

uva 11404 dp

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[l][r] = ans(dp[l][r-1], dp[l+1][r], s[l] + dp[l+1][r-1] + s[r]) dp存的是子序列,即一个s

UVA 11404 五 Palindromic Subsequence

Palindromic Subsequence Time Limit:3000MS     Memory Limit:0KB     64bit IO Format:%lld & %llu Submit Status Practice UVA 11404 1 #include <stdio.h> 2 #include <string.h> 3 #include <algorithm> 4 #include <string> 5 #include &l

*Maximum Length Palindromic Sub-Sequence of an Array.

/* Write a function to compute the maximum length palindromic sub-sequence of an array. A palindrome is a sequence which is equal to its reverse. A sub-sequence of an array is a sequence which can be constructed by removing elements of the array. Ex:

LeetCode 516. Longest Palindromic Subsequence

516. Longest Palindromic Subsequence Add to List Description Submission Solutions Total Accepted: 2159 Total Submissions: 5216 Difficulty: Medium Contributors: Stomach_ache Given a string s, find the longest palindromic subsequence's length in s. You

Longest Palindromic Substring &amp; Longest Palindromic Subsequence

5. Longest Palindromic Substring 题目链接:https://leetcode.com/problems/longest-palindromic-substring/#/description 题目大意:给定一个字符串s,返回该字符串的最长回文子串.s的最大长度不超过1000. 思路:对于每个子串的中心(可以是一个字符,或者是两个字符的间隙,比如串abc,中心可以是a,b,c,或者是ab的间隙,bc的间隙)往两边同时进行扫描,直到不是回文串为止.假设字符串的长度为n

516. Longest Palindromic Subsequence

本周课堂上学习的是动态规划,因此在LeetCode上找到相应的题进行练习. 题目: Given a string s, find the longest palindromic subsequence's length in s. You may assume that the maximum length of s is 1000. (给定一个字符串S,找到它的最长回文子序列长度) 示例: Example 1:Input  :"bbbab" Output:4 (One possibl