zoukankan      html  css  js  c++  java
  • 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; }

      

    自己选择的路,跪着也要走完。朋友们,虽然这个世界日益浮躁起来,只要能够为了当时纯粹的梦想和感动坚持努力下去,不管其它人怎么样,我们也能够保持自己的本色走下去。
  • 相关阅读:
    POJ 1953 World Cup Noise
    POJ 1995 Raising Modulo Numbers (快速幂取余)
    poj 1256 Anagram
    POJ 1218 THE DRUNK JAILER
    POJ 1316 Self Numbers
    POJ 1663 Number Steps
    POJ 1664 放苹果
    如何查看DIV被设置什么CSS样式
    独行DIV自适应宽度布局CSS实例与扩大应用范围
    python 从入门到精通教程一:[1]Hello,world!
  • 原文地址:https://www.cnblogs.com/WTSRUVF/p/9482229.html
Copyright © 2011-2022 走看看