• UVa11404


    题目大意

    给定一个字符串,要求你删除尽量少的字符,使得原字符串变为最长回文串,并把回文串输出,如果答案有多种,则输出字典序最小的

    题解

    有两种解法,第一种是把字符串逆序,然后求两个字符串的LCS,并记录LCS,长度就等于最长回文串的长度,不过求出来的LCS不一定是回文串,例如下面这个例子

            s  = 1 5 2 4 3 3 2 4 5 1
    reverse(s) = 1 5 4 2 3 3 4 2 5 1
           LCS = 1 5 2   3 3   4 5 1
    所以我们只需要LCS的前半段即可

    代码:

    #include <cstdio>
    #include <algorithm>
    #include <string>
    #include <iostream>
    #include <utility>
    using namespace std;
    #define MAXN 1005
    string a,b;
    pair<int,string>dp[MAXN][MAXN];
    int main()
    {
        while(cin>>a)
        {
            int len=a.length();
            b=a;
            reverse(b.begin(),b.end());
            for(int i=0;i<len;i++)
            {
                dp[0][i].first=0,dp[0][i].second="";
                dp[i][0].first=0,dp[i][0].second="";
            }
            for(int i=0;i<len;i++)
                for (int j=0;j<len;j++)
                    if(a[i]==b[j])
                    {
                        dp[i+1][j+1].first=dp[i][j].first+1;
                        dp[i+1][j+1].second=dp[i][j].second+a[i];
                    }
                    else
                    {
                        if(dp[i+1][j].first>dp[i][j+1].first)
                        {
                            dp[i+1][j+1].first=dp[i+1][j].first;
                            dp[i+1][j+1].second=dp[i+1][j].second;
                        }
                        else
                            if(dp[i+1][j].first==dp[i][j+1].first)
                            {
                                dp[i+1][j+1].first=dp[i][j+1].first;
                                dp[i+1][j+1].second=min(dp[i][j+1].second,dp[i+1][j].second);
                            }
                            else
                            {
                                dp[i+1][j+1].first=dp[i][j+1].first;
                                dp[i+1][j+1].second=dp[i][j+1].second;
                            }
                    }
                    int lens=dp[len][len].first;
                    string s=dp[len][len].second;
                    if(lens&1)
                    {
                        int t=lens/2;
                        for(int i=0;i<=t;i++)
                            cout<<s[i];
                        for(int i=t-1;i>=0;i--)
                            cout<<s[i];
                        cout<<endl;
                    }
                    else
                    {
                        int t=lens/2;
                        for(int i=0;i<t;i++)
                            cout<<s[i];
                        for(int i=t-1;i>=0;i--)
                            cout<<s[i];
                        cout<<endl;
                    }
        }
        return 0;
    }

    第二种方法和POJ1159一样,不过是多了个路径而已

    代码:

    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    #include <iostream>
    #include <string>
    using namespace std;
    #define MAXN 1005
    string s;
    int dp[MAXN][MAXN];
    string path[MAXN][MAXN];
    int main()
    {
        int n;
        while(cin>>s)
        {
            memset(dp,0,sizeof(dp));
            int n=s.length();
            for(int i=n-1; i>=0; i--)
                for(int j=i; j<n; j++)
                    if(s[i]==s[j])
                    {
                        dp[i][j]=dp[i+1][j-1];
                        if(i!=j)path[i][j]=s[i]+path[i+1][j-1]+s[j];
                        else
                            path[i][j]=s[i];
                    }
                    else
                    {
                        if(dp[i+1][j]<dp[i][j-1])
                        {
                            dp[i][j]=dp[i+1][j]+1;
                            path[i][j]=path[i+1][j];
                        }
                        else
                            if(dp[i+1][j]==dp[i][j-1])
                            {               
                                dp[i][j]=dp[i+1][j]+1;
                                path[i][j]=min(path[i+1][j],path[i][j-1]);
                            }
                            else
                            {
                                dp[i][j]=dp[i][j-1]+1;
                                path[i][j]=path[i][j-1]; 
                            }
                    }
                    cout<<path[0][n-1]<<endl;
        }
        return 0;
    }
  • 相关阅读:
    C#和sqlserver中生成新的32位GUID
    IIS7下swfupload上传大文件出现404错误
    jQuery 判断是否为数字的方法 及 转换数字函数
    js数组与字符串的相互转换方法
    jquery 中如何将数组转化为json字符串,然后再转化回来?
    Firemonkey Android 虚拟机
    Eclipse apk 签名
    win10 修改hosts
    eclipse 预览Android界面报错
    夜神模拟器
  • 原文地址:https://www.cnblogs.com/zjbztianya/p/3270505.html
Copyright © 2020-2023  润新知