UVA 11404 Palindromic Subsequence

原创 2016年08月29日 23:42:13

题目链接:http://acm.hust.edu.cn/vjudge/problem/28753


题意:给一个字符串,删除其中0个或多个字符,使得剩下的字母形成一个最长的回文串,输出字典序最小的。


思路:把字符串和它反向的字符串一起做一遍LCS。dp[i][j]表示从左边取i个字符,右边取j个字符的LCS。

回文串有两种:奇数长度和偶数长度的,我们分别枚举这两种情况更新答案。


#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <stack>
#include <map>
#include <set>
#include <vector>
#include <sstream>
#include <queue>
#include <utility>
using namespace std;

#define rep(i,j,k) for (int i=j;i<=k;i++)
#define Rrep(i,j,k) for (int i=j;i>=k;i--)

#define Clean(x,y) memset(x,y,sizeof(x))
#define LL long long
#define ULL unsigned long long
#define inf 0x7fffffff
#define mod 100000007

const int maxn = 1009;

struct node
{
    string str;
    int L;
    node()
    {
        L = 0;
        str = "";
    }
    bool operator > ( const node &x )
    {
        if ( L != x.L ) return L > x.L;
        return str < x.str;
    }
}dp[maxn][maxn];

char A[maxn],B[maxn];
int n;


void init()
{
    n = strlen(A+1);
    rep(i,1,n) B[i] = A[n-i+1];
}

void update1( int l , int r , node &ans )
{
    node temp;
    temp.L = dp[l][r].L * 2;
    if ( temp.L < ans.L ) return;
    temp.str = dp[l][r].str;
    Rrep(i,dp[l][r].L-1,0)
        temp.str += dp[l][r].str[i];
    if ( temp > ans ) ans = temp;
}


void update2(int mid,node &ans)
{
    node temp;
    temp.L = dp[mid-1][n-mid].L * 2 + 1;
    if ( temp.L < ans.L ) return;
    temp.str = dp[mid-1][n-mid].str;
    temp.str += A[mid];
    Rrep(i,dp[mid-1][n-mid].L-1,0)
        temp.str += dp[mid-1][n-mid].str[i];
    if ( temp > ans ) ans = temp;
}

void solve()
{
    rep(i,0,n) dp[0][i].L = dp[i][0].L = 0 , dp[0][i].str = dp[i][0].str = "";
    rep(i,1,n)
        rep(j,1,n)
        if ( A[i] == B[j] )
            dp[i][j].L = dp[i-1][j-1].L + 1 , dp[i][j].str = dp[i-1][j-1].str + A[i];
        else
        {
            if ( dp[i-1][j].L > dp[i][j-1].L )
                dp[i][j] = dp[i-1][j];
            else if ( dp[i-1][j].L < dp[i][j-1].L )
                dp[i][j] = dp[i][j-1];
            else dp[i][j] = dp[i-1][j]>dp[i][j-1]?dp[i-1][j]:dp[i][j-1];
        }
    node ans;
    rep(i,1,n-1) //偶数长度,分成两个区间
        update1( i , n - i , ans );
    rep(i,1,n) //奇数长度,i作为中间字符,分成两个区间
        update2(i,ans);
    cout<<ans.str<<endl;
}

int main()
{
    while( gets(A+1) )
    {
        init();
        solve();
    }
    return 0;
}


版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

UVA 11404-Palindromic Subsequence(DP)

题目大意:给出一个字符串,找出长度最长的回文子串,若有多个,找出字典序最小的。 用d[i][j]表示第i个字符到第j个字符的最长回文子串的长度。用b[i][j]表示第i个字符之后最近的一个值...

uva 11404 Palindromic Subsequence(LCS回文串,最小字典序)

题目大意 给一个字符串,输出它的最长回文串,如果有多个结果,输出字典序最小的。 我们都知道把一个字符串逆序后和原字符串进最长公共子序列,可以计算出它的最长回文串长度。 但是这题不仅要输出回文...

UVA 11404 Palindromic Subsequence LCS

点击打开题目链接 给一个由小写字母组成的字符串,输出它的最长回文串,如果有多个结果,输出字典序最小的。 正序和逆序求最长公共子序列,不过要字典序最小,这里用结构体(第二次用结构体做dp)。 ...

UVA 11404 Palindromic Subsequence 记忆化搜索

记忆化搜索,记录l和r之间的最大回文串数,因为还需要打印出来,所以再记录一下路径即可。 #include using namespace std; const int N=1100; int d[N...

uva 11404 Palindromic Subsequence

题意:求最长回文子序列,并且是最小子序列。 思路:求最长回文子序列可以将序列倒过来求一遍LCS,而这里要求字典序最小,可以开一个结构体同时更新字典序,不过求出来的并不一定是回文子序列。 比如: ...

UVA11404 - Palindromic Subsequence - 动态规划

这道题思路是找最少去掉几个字符可以构成回文,那么就可以倒序之后求LCS,注意,只需要

LeetCode 516. Longest Palindromic Subsequence

516. Longest Palindromic SubsequenceGiven a string s, find the longest palindromic subsequence’s len...

516. Longest Palindromic Subsequence

Longest Palindromic Subsequence

第八周:(LeetCode 516) Longest Palindromic Subsequence(c++)

原题: Given a string s, find the longest palindromic subsequence’s length in s. You may assume that t...

Longest Palindromic Subsequence

Longest Palindromic Subsequence (not substring, for the substring solution, please find answers in m...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)