• hiho 第1周 最长回文子串


    题目链接:http://hihocoder.com/problemset/problem/1032

    #include <bits/stdc++.h>
    using namespace std;
    
    bool table[10000][10000] = {false};
    
    string longestPalindromeDP(string s)
    {
        int n = s.length();
        int longestBegin = 0;
        int maxLen = 1;
        memset(table,0,sizeof(table));
        for (int i = 0; i < n; i++)
            table[i][i] = true;   //前期的初始化
    
    
        for (int len = 2; len <= n; len++)
        {
            for (int i = 0; i < n-len+1; i++)
            {
                int j = i+len-1;
                if (s[i] == s[j] && table[i+1][j-1])
                {
                    table[i][j] = true;
                    longestBegin = i;
                    maxLen = len;
                }
            }
        }
        return s.substr(longestBegin, maxLen);
    }
    
    int main()
    {
        int t;
        cin>>t;
        while(t--)
        {
            string str;
            cin>>str;
            string ans = longestPalindromeDP(str);
            cout<<ans.length()<<endl;
        }
        return 0;
    }
    View Code
    #include <bits/stdc++.h>
    using namespace std;
    
    const int maxn = 1000008;
    
    char instr[maxn],str[maxn*2];
    int rad[maxn*2];
    
    
    int Manacher()
    {
        int i,j,maxx;
        int n = strlen(instr);
        memset(str,'#',sizeof(str));
        for(i=0;i<n;i++)
            str[(i+1)<<1] = instr[i];
    
        n = (n+1)<<1;
        str[n] = '$';
        int maxRad;
        maxRad = j = maxx = 0;
        for(i = 0;i<n;i++)
        {
            if(i<maxx)
                rad[i] = min(rad[2*j-i],maxx-i);
            else rad[i] = 1;
    
            while(str[i-rad[i]]==str[i+rad[i]])
                rad[i] ++;
            if(maxRad<rad[i])
                maxRad = rad[i];
            if(rad[i]+i>maxx)
            {
                j = i;
                maxx = rad[i] + i;
            }
    
        }
        return maxRad;
    
    }
    
    int main()
    {
        int t;
        scanf("%d",&t);
        while(t--)
        {
            scanf("%s",instr);
            printf("%d
    ",Manacher()-1);
        }
        return 0;
    }
    View Code

    先是用DP写了一下,

    DP方程,就是用一个二维数组标记table[i][j] 字符串i,到j是否构成回文串,然后枚举最大长度len,

    要是两端相等,并且,可以扩展,那么longestBegin = i,maxlen = len;时间复杂度还是O(n^2),并且数组都开不了。

    然后就是Manacher算法:

    参考:http://www.cnblogs.com/lv-2012/archive/2012/11/15/2772268.html

    先扩充为两倍的字符串,rad[i]表示新的字符串第I个位置可以向左向右匹配的最大距离。求出这个rad数组,有一个结论,rad - 1就是原串对应的位置能匹配的最大长度。

    那么怎么求rad数组:

    求rad[i] 的时候,如果知道rad 前面的值,还有前面有个位置 ID,能够扩充的最大距离是max,

    那么rad = min(rad[2*id-i],max-i);

    原因:

    当 mx - i > P[j] 的时候,以S[j]为中心的回文子串包含在以S[id]为中心的回文子串中,由于 i 和 j 对称,
    以S[i]为中心的回文子串必然包含在以S[id]为中心的回文子串中,所以必有 P[i] = P[j],见下图。
       
      
       当 P[j] > mx - i 的时候,以S[j]为中心的回文子串不完全包含于以S[id]为中心的回文子串中,但是基于
    对称性可知,下图中两个绿框所包围的部分是相同的,也就是说以S[i]为中心的回文子串,其向右至少会
    扩张到mx的位置,也就是说 P[i] >= mx - i。至于mx之后的部分是否对称,就只能老老实实去匹配了。
      

  • 相关阅读:
    LoadRunner脚本增强技巧之参数化(二)
    LoadRunner脚本增强技巧之参数化(一)
    LoadRunner脚本增强技巧之手动关联
    LoadRunner脚本增强技巧之自动关联
    LoadRunner录制用户操作
    Fiddler绕过前端直接和后台进行交互
    Android手机Fiddler真机抓包
    zabbix自定义监控项二
    zabbix自定义监控项一
    zabbix主机自动发现和监控
  • 原文地址:https://www.cnblogs.com/TreeDream/p/5934967.html
Copyright © 2020-2023  润新知