• Best Reward HDU 3613(回文子串Manacher)


    题目大意:有一个串(全部由小写字母组成),现在要把它分成两部分,如果分开后的部分是回文串就计算出来它的价值总和,如果不是回文的那么价值就是0,最多能得到的最大价值。
     
    分析:首先的明白这个最大价值有可能是负数,比如下面:
    -1 -1 -1.....
    aaa
    这样的情况不管怎么分,分出来的串都是回文串,所以得到的最大价值是 -3。
    求回文串的算法使用的是Manacher算法,线性的复杂度。
     
    代码如下:
    ================================================================================================================
    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    using namespace std;
    
    const int MAXN = 1e6+7;
    const int MAXM = 1007;
    const int oo = 1e9+7;
    char str[MAXN];
    int p[MAXN], val[27], sum[MAXN];
    bool Left[MAXN], Right[MAXN];
    
    /**
    str[]   先存原字符串,后存扩展后的字符串
    p[]     p[i] 表示以i为中心的回文串有多长(只记录一边的长度)、
    sum[]   sum[i]表示前i个字符的总价值和
    Left[]  Left[i] 表示前缀长度为 i 的串是否是回文串
    Right[] Right[i]  表示后缀长度为 i 的串是否是回文串
    **/
    
    void Manacher(char str[], int N)
    {
        int i, id=0;
    
        for(i=2; i<N; i++)
        {
            if(p[id]+id > i)
                p[i] = min( p[id*2-i], p[id]+id-i);
            else p[i] = 1;
    
            while(str[ i+p[i] ] == str[ i-p[i] ])
                p[i]++;
    
            if(p[id]+id < p[i]+i)
                id = i;
    
            if(p[i] == i)
                Left[p[i]-1] = true;
            if(p[i]+i-1 == N)
                Right[p[i]-1] = true;
        }
    }
    
    int main()
    {
        int T;
    
        scanf("%d", &T);
    
        while(T--)
        {
            int i;
    
            memset(Left, false, sizeof(Left));
            memset(Right, false, sizeof(Right));
            memset(p, false, sizeof(p));
    
            for(i=0; i<26; i++)
                scanf("%d", &val[i]);
    
            scanf("%s", str);
    
            int len = strlen(str);
    
            for(i=1; i<=len; i++)
                sum[i] = sum[i-1]+val[str[i-1]-'a'];
    
            for(i=len; i>=0; i--)
            {
                str[i+i+2] = str[i];
                str[i+i+1] = '#';
            }
            str[0] = '$';
    
            Manacher(str, len+len+1);
    
            int ans = -oo;
    
            for(i=1; i<len; i++)
            {
                int temp = 0;
    
                if(Left[i] == true)
                    temp += sum[i];
                if(Right[len-i] == true)
                    temp += sum[len]-sum[i];
    
                ans = max(ans, temp);
            }
    
            printf("%d
    ", ans);
        }
    
        return 0;
    }
  • 相关阅读:
    2、容器初探
    3、二叉树:先序,中序,后序循环遍历详解
    Hebbian Learning Rule
    论文笔记 Weakly-Supervised Spatial Context Networks
    在Caffe添加Python layer详细步骤
    论文笔记 Learning to Compare Image Patches via Convolutional Neural Networks
    Deconvolution 反卷积理解
    论文笔记 Feature Pyramid Networks for Object Detection
    Caffe2 初识
    论文笔记 Densely Connected Convolutional Networks
  • 原文地址:https://www.cnblogs.com/liuxin13/p/4747537.html
Copyright © 2020-2023  润新知