Mejor recompensa [HDU - 3613] (manacher algoritmo)

Mejor recompensa [HDU - 3613] (manacher algoritmo)

HDU - 3613

Después de una dura batalla, el general Li ganó una gran victoria. Ahora el jefe de Estado resuelve la recompensa con honor y tesoros por su gran hazaña.

Uno de estos tesoros es un collar formado por 26 diferentes tipos de piedras preciosas, y la longitud del collar es n. (Es decir: n piedras preciosas son de cuerda juntos para constituir este collar, y cada una de estas piedras preciosas pertenece sólo a uno de los 26 tipos).

De acuerdo con la visión clásica, un collar es valiosa si y sólo si es un palíndromo - el collar se ve igual en cualquier dirección. Sin embargo, el collar que hemos mencionado anteriormente puede no un palíndromo al principio. Por lo que el jefe de Estado decide cortar el collar en dos partes, y luego dar los dos para el general Li.

Todas las piedras preciosas de la misma clase tienen el mismo valor (puede ser positivo o negativo, debido a su calidad - algunos tipos son hermosas mientras que otros pueden ve como piedras normales). Un collar que es palindrom tiene un valor igual a la suma del valor de sus piedras preciosas. mientras que un collar que no es palindrom tiene valor cero.

Ahora el problema es: cómo cortar el collar determinado de manera que la suma del valor de los dos collares es mayor. Salida de este valor.

Entrada

La primera línea de entrada es un único entero T (1 ≤ T ≤ 10) - el número de casos de prueba. La descripción de estos casos de prueba sigue.

Para cada caso de prueba, la primera línea es de 26 números enteros: v 1, v 2, ..., v 26 (-100 ≤ vi ≤ 100, 1 ≤ i ≤ 26), representan el valor de las piedras preciosas de cada tipo.

La segunda línea de cada caso de prueba es una cadena compuesta de Charactor 'a' a 'z'. que representa el collar. Charactor diferentes que representan diferentes tipos de piedras preciosas, y el valor de 'a' es v 1, el valor de 'b' es v 2, ..., y así sucesivamente. La longitud de la cadena de no más de 500000 es.

Salida

Salida de un solo entero: el valor máximo general Li puede llegar desde el collar.

Ejemplo de entrada

2
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
aba
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
acacac

Ejemplo de salida

1
6

Significado de las preguntas:

Dada una cadena s, y el carácter 'a' con el valor 'z',

Usted se pueden dividir en una cadena arbitraria de la sección de cuerda continua 2, el valor de cada parte es:

Si esta parte de la cadena es una cadena palíndromo, a continuación, el valor es el valor del carácter y contiene suma, de lo contrario el valor es 0.

El valor máximo se divide preguntará cuánta después?

ideas:

[I] representa un valor de cadena y 1 ~ i (cadena usando 1-index) suma: una matriz con el prefijo y

Con la cadena de procesamiento de algoritmo manacher s, obtener su más larga serie radio de capicúa \ (\ mathit p \)

Sabemos \ (p [i] -1 \ ) representante \ (\ mathit i \) como el centro de la longitud más larga del palíndromo.

Enumeramos la longitud del prefijo de la divisoria cadena de caracteres \ (i, i \ in [ 1, len-1] \)

A continuación, la longitud de la cadena s \ (\ mathit i \) prefijo \ (s [1 \ dots i ] \) es una secuencia palindrómica: \ (. P [. I + 1] - = 1 I \)

A continuación, la longitud de la cadena s \ (\ mathit i \) sufijo \ (s [len - i + 1 \ dots len] \) es una secuencia palindrómica: \ (P [I + len + 1.] - = 1. len - i \)

Para mantener el mayor valor.

código:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <vector>
#include <iomanip>
#include <sstream>
#include <bitset>
#define ALL(x) (x).begin(), (x).end()
#define sz(a) int(a.size())
#define rep(i,x,n) for(int i=x;i<n;i++)
#define repd(i,x,n) for(int i=x;i<=n;i++)
#define pii pair<int,int>
#define pll pair<long long ,long long>
#define gbtb ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define MS0(X) memset((X), 0, sizeof((X)))
#define MSC0(X) memset((X), '\0', sizeof((X)))
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define eps 1e-6
#define chu(x) cout<<"["<<#x<<" "<<(x)<<"]"<<endl
#define du3(a,b,c) scanf("%d %d %d",&(a),&(b),&(c))
#define du2(a,b) scanf("%d %d",&(a),&(b))
#define du1(a) scanf("%d",&(a));
using namespace std;
typedef long long ll;
ll gcd(ll a, ll b) {return b ? gcd(b, a % b) : a;}
ll lcm(ll a, ll b) {return a / gcd(a, b) * b;}
ll powmod(ll a, ll b, ll MOD) { if (a == 0ll) {return 0ll;} a %= MOD; ll ans = 1; while (b) {if (b & 1) {ans = ans * a % MOD;} a = a * a % MOD; b >>= 1;} return ans;}
ll poww(ll a, ll b) { if (a == 0ll) {return 0ll;} ll ans = 1; while (b) {if (b & 1) {ans = ans * a ;} a = a * a ; b >>= 1;} return ans;}
void Pv(const vector<int> &V) {int Len = sz(V); for (int i = 0; i < Len; ++i) {printf("%d", V[i] ); if (i != Len - 1) {printf(" ");} else {printf("\n");}}}
void Pvl(const vector<ll> &V) {int Len = sz(V); for (int i = 0; i < Len; ++i) {printf("%lld", V[i] ); if (i != Len - 1) {printf(" ");} else {printf("\n");}}}
inline long long readll() {long long tmp = 0, fh = 1; char c = getchar(); while (c < '0' || c > '9') {if (c == '-') fh = -1; c = getchar();} while (c >= '0' && c <= '9') tmp = tmp * 10 + c - 48, c = getchar(); return tmp * fh;}
inline int readint() {int tmp = 0, fh = 1; char c = getchar(); while (c < '0' || c > '9') {if (c == '-') fh = -1; c = getchar();} while (c >= '0' && c <= '9') tmp = tmp * 10 + c - 48, c = getchar(); return tmp * fh;}
const int maxn = 500010;
const int inf = 0x3f3f3f3f;
/*** TEMPLATE CODE * * STARTS HERE ***/
int val[maxn];
char s[maxn];
int len;
char s_new[maxn * 2 + 10];
int p[maxn * 2 + 10];
int Len;
int sum[maxn];
void init()
{
    Len = len * 2 + 2;
    int index = 0;
    s_new[index++] = '$';
    repd(i, 1, len)
    {
        s_new[index++] = '#';
        s_new[index++] = s[i];
    }
    s_new[index++] = '#';
    s_new[index++] = '\0';
    // chu(s_new);
}
void manacher()
{
    int R = 0;
    int mid = 0;
    repd(i, 1, Len)
    {
        p[i] = i < R ? min(R - i, p[2 * mid - i]) : 1;
        while (s_new[i - p[i]] == s_new[i + p[i]])
        {
            p[i]++;
        }
        if (i + p[i] > R)
        {
            R = i + p[i];
            mid = i;
        }
    }
}

int main()
{
    //freopen("D:\\code\\text\\input.txt","r",stdin);
    //freopen("D:\\code\\text\\output.txt","w",stdout);
    int t;
    t = readint();
    while (t--)
    {
        repd(i, 'a', 'z')
        {
            val[i] = readint();
        }
        scanf("%s", s + 1);
        len = strlen(s + 1);
        repd(i, 1, len)
        {
            sum[i] = sum[i - 1] + val[s[i]];
        }
        init();
        manacher();
        int ans = -inf;
        repd(i, 1, len - 1)
        {
            int temp = 0;
            if (p[i + 1] - 1 == i)
            {
                temp += sum[i];
            }
            if (p[i + 1 + len] - 1 == len - i)
            {
                temp += sum[len] - sum[i];
            }
            ans = max(ans, temp);
        }
        printf("%d\n", ans );
    }

    return 0;
}


Supongo que te gusta

Origin www.cnblogs.com/qieqiemin/p/12540629.html
Recomendado
Clasificación