zoukankan      html  css  js  c++  java
  • UVA 11404 简单LCS模型DP 字典序比较

    这个题目求某个字符串中含的最长的回文子串。

    就是一个很简单的LCS模型吗,而且我不明白为什么网上这么多人都说仿照某写法把字符串先逆序一下,然后求LCS,我只想问一下,有必要吗?

    直接按LCS的套路来就行了啊,只不过方式变了下,按上面的写法,又麻烦,又根本没利用的LCS的精髓思想

    即,先从间隔0位开始做起,然后是间隔1位。。2.。。n-1位,d[i][j]代表i到j的最长回文串个数

    于是就有 s[i]==s[j] d[i][j]=d[i+1][j-1]+2,否则就取 max(f[i+1][j],f[i][j-1]),不就行啦。还用得着上面那样搞?

    不过如果这个问题这么简单我也不会放到博客里来写了。主要是下面的问题,我还确实一开始没想到。

    比较麻烦的是当出现多个情况的时候 输出字典序小的,我一开始没想谨慎,很快的敲了,用个数组直接记录子串的字母的ASCII码值和,比较这个和来确定字典序,后来WA了几次才醒悟,这里肯定不能简单求ASCII和啊,比如 一个字符串里同时存在 adda和bccb,按我的做法,不是任意输出一个都行、、、显然不对嘛

    所以这个还是直接在计算的过程中,就把字符串求出来比较好,即按上面的推法,如果s[i]==s[j],把s[i]+已有回文串+s[j]组成新串即可,但是有个问题是,没有字符串函数是可以进行字符串的连接重组的,难道手写?还好C++的string是很强大的,直接可以进行+操作,并且可以直接进行比值,比出来直接就是字典序,那简直方便得不得了啊。

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <string>
    #define INF 1<<30
    using namespace std;
    int d[1010][1010];
    double cnt[1010][1010];
    string str[1010][1010];
    char s[1010];
    int len;
    //void print(int l,int r)
    //{
    //    if (l>r) return;
    //    if (s[l]==s[r])
    //    {
    //        printf("%c",s[l]);
    //        print(l+1,r-1);
    //        if (l<r)
    //         printf("%c",s[r]);
    //        return;
    //    }
    //    if (d[l+1][r]>d[l][r-1])
    //    {
    //        print(l+1,r);
    //        return;
    //    }
    //    if (d[l+1][r]<d[l][r-1])
    //    {
    //        print(l,r-1);
    //        return;
    //    }
    //    if (d[l+1][r]==d[l][r-1])
    //    {
    //        if (cnt[l+1][r]<cnt[l][r-1])
    //        {
    //            print(l+1,r);
    //        }
    //        else
    //            print(l,r-1);
    //    }
    //
    //}
    int main()
    {
        while (scanf("%s",&s)!=EOF)
        {
            len=strlen(s);
            memset(d,0,sizeof d);
           // memset(cnt,0,sizeof cnt);
            for (int i=0;i<len;i++)
            {
                for (int j=0;j+i<len;j++)
                {
                    int k=j+i;
                    int chj=s[j];
                    int chk=s[k];
                    if (s[j]==s[k])
                    {
                        if (i==0)
                        {
                            d[j][k]=1;
                            str[j][k]=s[j];
                        }
                        else{
                         d[j][k]=d[j+1][k-1]+2;
                         str[j][k]=s[j]+str[j+1][k-1]+s[k];
                        }
                    }
                    else
                    {
                        if (d[j][k-1]>d[j+1][k])
                        {
                            d[j][k]=d[j][k-1];
                            str[j][k]=str[j][k-1];
                        }
                        else
                        if (d[j][k-1]<d[j+1][k])
                        {
                            d[j][k]=d[j+1][k];
                            str[j][k]=str[j+1][k];
                        }
                        else
                        if (d[j][k-1]==d[j+1][k])
                        {
                            d[j][k]=d[j+1][k];
                            if (str[j][k-1]<str[j+1][k]) //直接string进行比值操作就可知道字典序大小
                                str[j][k]=str[j][k-1];
                            else
                                str[j][k]=str[j+1][k];
                        }
                    }
                }
            }
            cout<<str[0][len-1]<<endl;//直接输出该string即可
          //print(0,len-1);
            //printf("
    ");
        }
        return 0;
    }
  • 相关阅读:
    Selenium+Pytest自动化测试框架实战
    WPF性能优化经验总结
    C#跨窗体调用控件
    C# lock
    硬实时系统,到底多硬才算Hard Real Time System
    [GPIO]推荐一种超简单的硬件位带bitband操作方法,让变量,寄存器控制,IO访问更便捷,无需用户计算位置
    【STM32F407的DSP教程】第50章 STM32F407的样条插补实现,波形拟合丝滑顺畅
    实战技能分享,如何让工程代码各种优化等级通吃,含MDK AC5,AC6,IAR和GCC
    【深入探讨】DMA到底能不能起到加速程序执行的作用,DMA死等操作是否合理,多个DMA数据流同时刷是否处理过来
    《安富莱嵌入式周报》第238期:2021.11.012021.11.07
  • 原文地址:https://www.cnblogs.com/kkrisen/p/3619619.html
Copyright © 2011-2022 走看看