• Best Reward HDU


    题意:

      给你一串字符串,每个字符都有一个权值,要求把这个字符串在某点分开,使之成为两个单独的字符串

      如果这两个子串某一个是回文串,则权值为那一个串所有的字符权值和

      若不是回文串,则权值为0

    解析:

    先用Manacher算法求出以每个字母为中心的回文串的长度,并计算该字符串的前缀价值和。然后枚举切割点,得到两份子串。这样就可以知道每个子串的中心点,然后检查以该子串的中心点作为中心点的回文串的长度,如果长度等于该子串的长度,那么就加上该子串的价值。然后和最优价值比较就行了。

    注意只有一个字符时输出0

    #include <iostream>
    #include <cstdio>
    #include <sstream>
    #include <cstring>
    #include <map>
    #include <set>
    #include <vector>
    #include <stack>
    #include <queue>
    #include <algorithm>
    #include <cmath>
    #define rap(i, a, n) for(int i=a; i<=n; i++)
    #define rep(i, a, n) for(int i=a; i<n; i++)
    #define lap(i, a, n) for(int i=n; i>=a; i--)
    #define lep(i, a, n) for(int i=n; i>a; i--)
    #define rd(a) scanf("%d", &a)
    #define rlld(a) scanf("%lld", &a)
    #define rc(a) scanf("%c", &a)
    #define rs(a) scanf("%s", a)
    #define MOD 2018
    #define LL long long
    #define ULL unsigned long long
    #define Pair pair<int, int>
    #define mem(a, b) memset(a, b, sizeof(a))
    #define _  ios_base::sync_with_stdio(0),cin.tie(0)
    //freopen("1.txt", "r", stdin);
    using namespace std;
    const int maxn = 500010, INF = 0x7fffffff;
    char s[maxn], s_new[maxn<<1];
    int p[maxn<<1], a[30], sum[maxn];
    
    int init(char *s)
    {
        int len = strlen(s);
        s_new[0] = '$';
        s_new[1] = '#';
        int j = 2;
        rep(i, 0, len)
        {
            s_new[j++] = s[i];
            s_new[j++] = '#';
        }
        s_new[j++] = '';
       // cout<< strlen(s_new) <<endl;
        return j;
    }
    
    void manacher(char *s)
    {
        int len = init(s);
     //   int max_len = -1;
        int id, mx = 0;
        rep(i, 1, len)
        {
            if(i < mx)
                p[i] = min(p[2*id-i], mx - i);
            else
                p[i] = 1;
            while(s_new[i-p[i]] == s_new[i+p[i]])
                p[i]++;
            if(mx < i+p[i])
            {
                id = i;
                mx = i+p[i];
            }
        }
    }
    
    
    int T;
    int main()
    {
        rd(T);
        while(T--)
        {
            rep(i, 0, 26)
                rd(a[i]);
            rs(s);
            if(strlen(s) == 1)
            {
                cout<< "0" <<endl;
                continue;
            }
            sum[0] = a[s[0] - 'a'];
            int len = strlen(s);
            rep(i, 1, len){
                sum[i] = sum[i-1] + a[s[i] - 'a'];
             //   cout<< sum[i] <<endl;
            }
            manacher(s);
            int len2 = strlen(s_new);
            int res = -INF;
            for(int i=3; i<len2 - 2; i+=2)
            {
                int ans = 0;
                if(p[i/2+1] - 1 == i/2) ans += sum[i/2-1];
                if(p[i+(len2-i)/2] - 1 == (len2-i)/2) ans += sum[len-1] - sum[i/2-1];
                res = max(res, ans);
            }
            cout<< res <<endl;
    }
    return 0; }

      

    自己选择的路,跪着也要走完。朋友们,虽然这个世界日益浮躁起来,只要能够为了当时纯粹的梦想和感动坚持努力下去,不管其它人怎么样,我们也能够保持自己的本色走下去。
  • 相关阅读:
    AOP面向切面编程相关核心概念
    什么是AOP?
    vue-koa-mongodb管理系统
    js算法(个人整理_彦超)
    前端面试基础总结(个人整理_彦超)
    HTTP 知识点总结(个人整理_彦超)
    前端手写代码整理(个人整理_彦超)
    小程序框架
    nvm 的安装与使用
    three.js 火焰效果
  • 原文地址:https://www.cnblogs.com/WTSRUVF/p/9482229.html
Copyright © 2020-2023  润新知