• 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;
    }
  • 相关阅读:
    公开课 | 高段位的测试开发工程师是如何养成的?
    测试面试真题 | 从屡次碰壁到成长蜕变,半年拿下某大厂 60W 年薪测试开发 Offer!
    Git实战(五)| 让工作更高效,搞定Git的分支管理
    双 11 钜惠 | 测试开发爆款课程全年最低价,送 Mate40Pro、Kindle、华为手环等万元豪礼!
    测试面经 | 从测试螺丝钉到大厂测试开发,三点成长心得和面试经验
    Sql Server 常用函数
    IE Web Control介绍以及TreeView 控件树形结构不能显示的问题
    一个javascript脚本写的时钟
    使用DataGrid控件实现主细表
    解决 SQL Server 耗尽内存的情况
  • 原文地址:https://www.cnblogs.com/kkrisen/p/3619619.html
Copyright © 2020-2023  润新知