zoukankan      html  css  js  c++  java
  • LPS UVA 11404 Palindromic Subsequence

    题目传送门

    题意:求LPS (Longest Palidromic Subsequence) 最长回文子序列。和回文串不同,子序列是可以不连续的。

    分析:1. 推荐->还有一种写法是用了LCS的思想,dp[i][j]表示i到j的最长回文串长度,状态转移方程:

          1. dp[j][j+i-1] = dp[j+1][j+i-2] + 2; (str[j] == str[j+i-1])

          2. dp[j][j+i-1] = max (dp[j+1][j+i-1], dp[j][j+i-2]); (str[j] != str[j+i-1])

       2. 转化为LCS问题,将字符串逆序,然后和本串求LCS就是LPS的长度,但是前一半是LPS的一半,可以补全

    代码1:

    /************************************************
     * Author        :Running_Time
     * Created Time  :2015-8-7 14:26:22
     * File Name     :UVA_11404.cpp
     ************************************************/
    
    #include <cstdio>
    #include <algorithm>
    #include <iostream>
    #include <sstream>
    #include <cstring>
    #include <cmath>
    #include <string>
    #include <vector>
    #include <queue>
    #include <deque>
    #include <stack>
    #include <list>
    #include <map>
    #include <set>
    #include <bitset>
    #include <cstdlib>
    #include <ctime>
    using namespace std;
    
    #define lson l, mid, rt << 1
    #define rson mid + 1, r, rt << 1 | 1
    typedef long long ll;
    const int MAXN = 1e3 + 10;
    const int INF = 0x3f3f3f3f;
    const int MOD = 1e9 + 7;
    string ans[MAXN][MAXN];
    int dp[MAXN][MAXN];
    char str[MAXN];
    
    void LPS(void)  {
        int len = strlen (str + 1);
        memset (dp, 0, sizeof (dp));
        for (int i=1; i<=len; ++i)  dp[i][i] = 1;
        for (int i=1; i<=len; ++i)  ans[i][i] = str[i];
    
        for (int i=2; i<=len; ++i)   {              //区间长度
            for (int j=1; j+i-1<=len; ++j)  {       //[j, j+i-1]
                if (str[j] == str[j+i-1])   {
                    if (i == 2) {
                        dp[j][j+i-1] = 2;
                        ans[j][j+i-1] = ans[j][j] + ans[j+i-1][j+i-1];  continue;
                    }
                    dp[j][j+i-1] = dp[j+1][j+i-2] + 2;
                    ans[j][j+i-1] = str[j] + ans[j+1][j+i-2] + str[j+i-1];
                }
                else if (dp[j+1][j+i-1] > dp[j][j+i-2]) {
                    dp[j][j+i-1] = dp[j+1][j+i-1];
                    ans[j][j+i-1] = ans[j+1][j+i-1];
                }
                else if (dp[j][j+i-2] > dp[j+1][j+i-1]) {
                    dp[j][j+i-1] = dp[j][j+i-2];
                    ans[j][j+i-1] = ans[j][j+i-2];
                }
                else    {
                    dp[j][j+i-1] = dp[j+1][j+i-1];
                    ans[j][j+i-1] = min (ans[j+1][j+i-1], ans[j][j+i-2]);
                }
            }
        }
        int mlen = dp[1][len];
        for (int i=0; i<mlen; ++i)  {
            printf ("%c", ans[1][len][i]);
        }
        puts ("");
    }
    
    int main(void)    {     //UVA 11404 Palindromic Subsequence
        while (scanf ("%s", str + 1) == 1)  {
            LPS ();
        }
    
        return 0;
    }
    

    代码2:

    /************************************************
    * Author        :Running_Time
    * Created Time  :2015-8-7 14:26:22
    * File Name     :UVA_11404.cpp
     ************************************************/
    
    #include <cstdio>
    #include <algorithm>
    #include <iostream>
    #include <sstream>
    #include <cstring>
    #include <cmath>
    #include <string>
    #include <vector>
    #include <queue>
    #include <deque>
    #include <stack>
    #include <list>
    #include <map>
    #include <set>
    #include <bitset>
    #include <cstdlib>
    #include <ctime>
    using namespace std;
    
    #define lson l, mid, rt << 1
    #define rson mid + 1, r, rt << 1 | 1
    typedef long long ll;
    const int MAXN = 1e3 + 10;
    const int INF = 0x3f3f3f3f;
    const int MOD = 1e9 + 7;
    struct Ans  {
        int len;
        string s;
    }dp[MAXN][MAXN];
    char str[MAXN], rstr[MAXN];
    
    int main(void)    {
        while (scanf ("%s", str + 1) == 1)  {
            int len = strlen (str + 1);
            for (int i=1; i<=len; ++i)  {
                rstr[len-i+1] = str[i];
            }
            for (int i=0; i<=len; ++i)  {
                dp[0][i].len = 0, dp[0][i].s = "";
            }
            for (int i=1; i<=len; ++i)  {
                for (int j=1; j<=len; ++j)  {
                    if (str[i] == rstr[j])  {
                        dp[i][j].len = dp[i-1][j-1].len + 1;
                        dp[i][j].s = dp[i-1][j-1].s + str[i];
                    }
                    else if (dp[i][j-1].len > dp[i-1][j].len)   {
                        dp[i][j].len = dp[i][j-1].len;
                        dp[i][j].s = dp[i][j-1].s;
                    }
                    else if (dp[i-1][j].len > dp[i][j-1].len)   {
                        dp[i][j].len = dp[i-1][j].len;
                        dp[i][j].s = dp[i-1][j].s;
                    }
                    else    {
                        dp[i][j].len = dp[i-1][j].len;
                        dp[i][j].s = min (dp[i-1][j].s, dp[i][j-1].s);
                    }
                }
            }
            int mlen = dp[len][len].len;
            string ans = dp[len][len].s;
            for (int i=0; i<mlen/2; ++i)  printf ("%c", ans[i]);
            int j;
            if (mlen & 1)   j = mlen / 2;
            else    j = mlen / 2 - 1;
            for (; j>=0; --j)   printf ("%c", ans[j]);
            puts ("");
        }
    
        return 0;
    }
    

     

    编译人生,运行世界!
  • 相关阅读:
    使用Delphi自带的TDockTabSet组件实现停靠功能(Jeremy North)
    揭秘换肤技术(转载)
    cdecl、stdcall、fastcall函数调用约定区别(转)
    Delphi XE的RTTI增强,动态Hook某些内部事件
    sizeof和strlen解析
    由swap引出的局部变量,形参和指针的小问题
    单链表的逆置算法
    关于C++中的虚拟继承的一些总结
    关于"引用"的几点说明
    求最长公共子序列(子序列在原串中可以不连续)
  • 原文地址:https://www.cnblogs.com/Running-Time/p/4711165.html
Copyright © 2011-2022 走看看