Best Reward HDU - 3613(Manacher)

Best Reward HDU - 3613

题目链接:https://cn.vjudge.net/contest/163024#problem/S
题目大意:26个字母,每个都有一个权值,给定一字符串,将这个字符串分给成两部分,分割后的两部分,如果该部分是回文的话它的价值就是所有字母的权值和,否则就是0。

input

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

output

1
6
题目分析:可以预处理一下,这个串在第i点分隔开之后是否是回文,然后用前缀和处理一下权值即可。

#include <bits/stdc++.h>
using namespace std;

const int maxn = 1e6 + 10;

int p[maxn], v[30], sum[maxn], cnt, len;
bool Left[maxn], Right[maxn];
char str[maxn], s[maxn];

void init()
{
    memset(p, 0, sizeof(p));
    int i;
    cnt = 0;
    str[cnt++] = '$';
    for(i = 0; i < len; i++)
    {
        str[cnt++] = '#';
        str[cnt++] = s[i];
    }
    str[cnt++] = '#';
    str[cnt] = '\0';
}

void manacher()
{
    init();
    int po = 0, maxr = 0;
    for(int i = 1; i < cnt; i++)
    {
        if(maxr > i) p[i] = min(p[po * 2 - i], maxr - i);
        else p[i] = 1;

        while(str[i + p[i]] == str[i - p[i]]) p[i]++;

        if(i + p[i] > maxr)
        {
            maxr = i + p[i];
            po = i;
        }
        if(p[i] == i) Left[i - 1] = true;
        if(p[i] + i  == cnt) Right[p[i] - 1] = true;
    }
}

int main()
{
    int t, i;
    scanf("%d", &t);
    while(t--)
    {
        for(i = 0; i < 26; i++)
            scanf("%d", &v[i]);

        scanf("%s", s);
        len = strlen(s);

        memset(sum, 0, sizeof(sum));
        memset(Left, false, sizeof(Left));
        memset(Right, false, sizeof(Right));
        sum[0] = v[s[0] - 'a'];
        for(i = 1; i < len; i++)
        {
            sum[i] = sum[i - 1] + v[s[i] - 'a'];
        }

        manacher();

        int ans = 0;
        for(i = 1; i < len; i++)
        {
            int tmp = 0;
            if(Left[i])
            {
                tmp += sum[i - 1];
            }
            if(Right[len - i])
            {
                tmp += sum[len - 1] - sum[i - 1];
            }

            ans = max(tmp, ans);

        }

        printf("%d\n", ans);
    }
}

弄不懂的地方是:

  if(p[i] == i) Left[i - 1] = true;
  if(p[i] + i  == cnt) Right[p[i] - 1] = true;

这两行代码。
举个例子:abaaba
处理之后的是这样的

位置:0 1 2 3 4 5 6 7 8 9 10 11 12 13
字符:$ # a # b # a # a #  b  #  a  #
p[i]:  1 2 1 4 1 2 7 2 1  4  1  2  1

p[4] = 4,这时left[3] = true; 它的意思是 前缀 aba是个回文串。因为p[4] = 4,说明在str[1~3]个字符与后边[5~7]个字符组成了回文(当然是加上了4个字符),因为这个字符串是加上了#的,所以p[4]=4,是说明一共有3 * 2 + 1个字符,对应回原来的就是i- 1;
right同理,只不过处理的是后缀。

阅读更多

Best Reward

11-05

Problem DescriptionnAfter an uphill battle, General Li won a great victory. Now the head of state decide to reward him with honor and treasures for his great exploit. nnOne of these treasures is a necklace made up of 26 different kinds of gemstones, and the length of the necklace is n. (That is to say: n gemstones are stringed together to constitute this necklace, and each of these gemstones belongs to only one of the 26 kinds.) nnIn accordance with the classical view, a necklace is valuable if and only if it is a palindrome - the necklace looks the same in either direction. However, the necklace we mentioned above may not a palindrome at the beginning. So the head of state decide to cut the necklace into two part, and then give both of them to General Li. nnAll gemstones of the same kind has the same value (may be positive or negative because of their quality - some kinds are beautiful while some others may looks just like normal stones). A necklace that is palindrom has value equal to the sum of its gemstones' value. while a necklace that is not palindrom has value zero. nnNow the problem is: how to cut the given necklace so that the sum of the two necklaces's value is greatest. Output this value. nn nnInputnThe first line of input is a single integer T (1 ≤ T ≤ 10) - the number of test cases. The description of these test cases follows. nnFor each test case, the first line is 26 integers: v1, v2, ..., v26 (-100 ≤ vi ≤ 100, 1 ≤ i ≤ 26), represent the value of gemstones of each kind. nnThe second line of each test case is a string made up of charactor 'a' to 'z'. representing the necklace. Different charactor representing different kinds of gemstones, and the value of 'a' is v1, the value of 'b' is v2, ..., and so on. The length of the string is no more than 500000. nn nnOutputnOutput a single Integer: the maximum value General Li can get from the necklace.n nnSample Inputn2n1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1naban1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1nacacacn nnSample Outputn1n6

没有更多推荐了,返回首页