zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    将空值转换为实际值
    图像的几何变换(一)
    图像的代数运算
    灰度直方图均衡化的算数推导
    图像的点运算
    探索数据可视化,业务数据是核心
    Gazebo機器人仿真學習探索筆記(一)安裝與使用
    脐带血要不要保存?看了你就明白!
    linuxsvn源代码版本库建立
    svn(subversion)代码版本管理在linux下的一些常见使用命令
  • 原文地址:https://www.cnblogs.com/zjbztianya/p/3270505.html
Copyright © 2011-2022 走看看