码迷,mamicode.com
首页 > 其他好文 > 详细

UVA 11404 Plalidromic Subsquence

时间:2015-10-01 23:00:03      阅读:270      评论:0      收藏:0      [点我收藏+]

标签:

最长回文子序列可以用求解原串s和反转串rv的LCS来得到,因为要求回文串分奇偶,dp[i][j]保存长度,

要求字典序最小,dp[i][j]应该表示回文串的端点,所以边界为单个字符,即i+j=len+1。

这题最麻烦的地方在于字典序,我是写了个比较函数,有点暴力(常数大)。

也可以反着定义,这时结点就要保存那个状态的字符串了(这样定义比较字典序的时候常数小)

#include<bits/stdc++.h>
using namespace std;

#define MP make_pair
#define fi first
#define se second

const int LEN = 1e3+5;
char s[LEN],rv[LEN];
int dp[LEN][LEN];
pair<int,int> pre[LEN][LEN];
char val[LEN][LEN];

inline void updata(int i,int j,int v,char c,const pair<int,int> &prv)
{
    dp[i][j] = v;
    pre[i][j] = prv;
    val[i][j] = c;
}

const auto nil = MP(0,0);

#define dim(x) [x.fi][x.se]
bool cmpLex(pair<int,int> a,pair<int,int> b)
{
    //
    while(a != nil && val[a.fi][a.se] == val[b.fi][b.se]){
        a = pre dim(a); b = pre dim(b);
    }
    return val dim(a) < val dim(b);
}

//#define LOCAL
int main()
{
#ifdef LOCAL
    freopen("in.txt","r",stdin);
#endif

    while(gets(s)){
        int len = strlen(s);
        for(int i = 0; i < len; i++){
            rv[len-1-i] = s[i];
        }
        int hd1,hd2,vl = 0;
        for(int i = 1; i <= len; i++){
            int j = len+1-i;
            dp[i][j] = 1; val[i][j] = s[i-1]; pre[i][j] = nil;
            if(dp[i][j] > vl || ( dp[i][j] == vl && cmpLex( MP(i,j), MP(hd1,hd2) ) ) ){//
                vl = dp[i][j];
                hd1 = i; hd2 = j;
            }
            for(int k = 1; k < j; k++) dp[i][k] = 0;
            for(j++; j <= len; j++){
                if(s[i-1] == rv[j-1]){
                    updata(i,j,dp[i-1][j-1]+2,s[i-1],make_pair(i-1,j-1));
                    if(dp[i][j] > vl || (dp[i][j] == vl && cmpLex(MP(i,j),MP(hd1,hd2)) ) ){//
                        vl = dp[i][j];
                        hd1 = i; hd2 = j;
                    }
                }else {
                    if(dp[i-1][j] > dp[i][j-1] || (dp[i-1][j] == dp[i][j-1] && cmpLex(MP(i-1,j),MP(i,j-1)) ) ){//
                        updata(i,j,dp[i-1][j],val[i-1][j],pre[i-1][j]);
                    }else {
                        updata(i,j,dp[i][j-1],val[i][j-1],pre[i][j-1]);
                    }
                }

            }
        }
        int pv = (vl+1)>>1,ln = vl;

        auto u = MP(hd1,hd2);
        for(int i = 0; i < pv; i++){
            s[i] = val[u.fi][u.se];
            u = pre[u.fi][u.se];
        }

        s[ln] = \0;
        for(int i = pv; i < ln; i++){
            s[i] = s[ln-1-i];
        }
        puts(s);
    }
    return 0;
}

 

UVA 11404 Plalidromic Subsquence

标签:

原文地址:http://www.cnblogs.com/jerryRey/p/4851673.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!