UVA 11404 简单LCS模型DP 字典序比较

摘要:
这个问题是查找字符串中包含的最长回文子字符串。它是一个非常简单的LCS模型吗?我不明白为什么网上有这么多人说他们按照某种写法把字符串颠倒过来,然后计算LCS。我只是想问,有必要吗?直接遵循LCS的常规是可以的,但方式已经改变了。遵循上述写作方法既麻烦又无用。LCS的本质是从间隔0开始,然后从间隔1..2开始N-1位,d[i][j]表示从i到j的最长回文字符串,因此s[i]==s[

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

就是一个很简单的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;
}

免责声明:文章转载自《UVA 11404 简单LCS模型DP 字典序比较》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇10.深入k8s:调度的优先级及抢占机制源码分析[转]Oracle 创建 DBLink 的方法下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

Opencv 图片边缘检测和最小外接矩形

1 #include "core/core.hpp" 2 #include "highgui/highgui.hpp" 3 #include "imgproc/imgproc.hpp" 4 #include "iostream" 5 #include "cmath" 6 using namespacestd; 7 using namespacecv; 8...

在鲲鹏916服务器上编译和安装dpdk踩坑

 无法爬楼楼的可以从这里下: http://static.dpdk.org/rel/ [root@kunpeng82 data1]# cat /etc/default/grub |grep GRUB_CMDLINE_LINUX GRUB_CMDLINE_LINUX="crashkernel=auto" GRUB_CMDLINE_LINUX_DEFAU...

JEECMS站群管理系统-- 标签使用和模板的制作

1模板规划 1.1资源文件 资源文件就是网页中用到的图片、CSS、JS等元素,在CMS系统中所有的资源文件在网站的根目录中的 /res_base/所属网站定义资源目录/TEMPLEATE/WEB /res_base/所属网站定义资源目录/TEMPLEATE/WAP 解释:网站定义资源 在CMS系统中可以同时管理多个网站,也就是多个网站可以同时使用一套CMS...

Linux C语言头文件搜索路径

本文介绍在linux中头文件的搜索路径,也就是说你通过include指定的头文件,linux下的gcc编译器它是怎么找到它的呢。在此之前,先了解一个基本概念。     头文件是一种文本文件,使用文本编辑器将代码编写好之后,以扩展名.h保存就行了。头文件中一般放一些重复使用的代码,例如函数声明、变量声明、常数定义、宏的定义等等。当使用#include语句将...

java栈、堆

一。栈、堆几个小概念 1.寄存器:最快的存储区, 由编译器根据需求进行分配,我们在程序中无法控制. 2. 栈:存放基本类型的变量数据和对象的引用,但对象本身不存放在栈中,而是存放在堆(new 出来的对象)或者常量池中(字符串常量对象存放在常量池中。) 3. 堆:存放所有new出来的对象。 4. 静态域 :存放静态成员(static定义的) 5. 常量池 :...

字符串(二):string

字符串使用方法整理 系列: 字符串(一):char 数组 字符串(二):string string 是 C++ STL 的一个字符串类型,原型是 vector<char> 并对字符串处理做了优化。 1. 声明 首先要包括库文件 #include <string>,这个 <string> 不同于 <cstr...