HDU 3613 Best Reward(KMP算法求解一个串的前、后缀回文串标记数组)
2018-07-23 08:51
507 查看
题目链接:
https://cn.vjudge.net/problem/HDU-3613
After 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.
One 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.)
In 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.
All 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.
Now the problem is: how to cut the given necklace so that the sum of the two necklaces's value is greatest. Output this value.
InputThe first line of input is a single integer T (1 ≤ T ≤ 10) -
the number of test cases. The description of these test cases follows.
For each test case, the first line is 26 integers: v
1, v
2, ..., v
26 (-100 ≤ v
i ≤ 100, 1 ≤ i ≤ 26), represent the value of gemstones of each kind.
The 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 v
1, the value of 'b' is v
2, ..., and so on. The length of the string is no more than 500000.
OutputOutput a single Integer: the maximum value General Li can get from the necklace.Sample Input
Sample Output
https://cn.vjudge.net/problem/HDU-3613
After 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.
One 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.)
In 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.
All 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.
Now the problem is: how to cut the given necklace so that the sum of the two necklaces's value is greatest. Output this value.
InputThe first line of input is a single integer T (1 ≤ T ≤ 10) -
the number of test cases. The description of these test cases follows.
For each test case, the first line is 26 integers: v
1, v
2, ..., v
26 (-100 ≤ v
i ≤ 100, 1 ≤ i ≤ 26), represent the value of gemstones of each kind.
The 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 v
1, the value of 'b' is v
2, ..., and so on. The length of the string is no more than 500000.
OutputOutput a single Integer: the maximum value General Li can get from the necklace.Sample 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
Sample Output
1 6
1 /* 2 题意描述 3 输入26个小写字母的价值,再输入一个字符串,问从哪个位置分割开,两个串的价值之和最大,当分成的串是回文串的时候,价值是各个字母的 4 和,不是回文串的时候,价值为0 5 6 解题思路 7 问题的关键是如何判断从哪个位置分割开后,前缀和后缀是不是回文串,普通的办法时间复杂度太高。 8 具体做法是将原s串反转赋值给t,拿s去匹配t,跑一遍kmp,得到s串的最大前缀子串的位置temp 9 同理拿t串去匹配s,跑一边kmp,得到s串的最大后缀子串的位置temp 10 由next数组的特性可知,将temp的位置标记为前缀回文后,寻找之前一个的前缀回文,也即next[temp]里面存的是之前一个前缀回文串的位置 11 ,然后标记,如此循环,直到temp=0,表示没有前缀回文串,同理可得到后缀子串的回文标记数组。然后枚举每一个分割位置,判断是否时是 12 回文,计算求解最大值,其中利用前缀和数组加快计算。 13 */ 14 #include<cstdio> 15 #include<cstring> 16 17 const int maxn = 500010; 18 const int inf=99999999; 19 char s[maxn], t[maxn]; 20 int val[26], next[maxn], presum[maxn]; 21 bool pre[maxn], pos[maxn]; 22 23 void get_next(char b[], int len); 24 int kmp(char a[], char b[], int len); 25 26 int main() 27 { 28 int T; 29 scanf("%d", &T); 30 while( T-- ){ 31 for(int i = 0; i < 26; i++){ 32 scanf("%d", &val[i]); 33 } 34 scanf("%s", s); 35 int len = strlen(s); 36 for(int i=0;i<len;++i) 37 t[i] = s[len - 1 - i],presum[i + 1] = presum[i] + val[s[i] - 'a']; 38 t[len]='\0'; 39 40 memset(next,0,sizeof(next)); 41 get_next(s,len); 42 int temp=kmp(s,t,len);//拿s去匹配t,也即t是主串,s是副串 43 memset(pre, 0, sizeof(pre)); 44 while(temp){ 45 pre[temp] = 1; 46 temp = next[temp]; 47 } 48 49 memset(next,0,sizeof(next)); 50 get_next(t,len); 51 temp=kmp(t,s,len); 52 memset(pos, 0, sizeof(pos)); 53 while(temp){ 54 pos[temp] = 1; 55 temp = next[temp]; 56 } 57 58 int ans = -inf; 59 for(int i = 1; i < len; i++){ 60 int sum = 0; 61 if(pre[i]) 62 sum += presum[i]; 63 if(pos[len - i]) 64 sum += presum[len] - presum[i]; 65 if(sum > ans) 66 ans = sum; 67 } 68 printf("%d\n",ans); 69 } 70 return 0; 71 } 72 73 74 int kmp(char a[], char b[], int len){//注意a是副串,b是主串 75 int i=0; 76 int j=0; 77 while(i < len && j < len){ 78 if(j == -1 || a[j] == b[i]){ 79 i++; 80 j++; 81 } 82 else 83 j=next[j]; 84 } 85 return j;//返回副串,也就是原串的最后匹配位置,故前j称为原串的最大前缀回文子串 86 } 87 88 void get_next(char a[], int len){ 89 int i = 0; 90 int j = -1; 91 next[0] = -1; 92 while(i < len){ 93 if(j == -1 || a[i] == a[j]){ 94 i++; 95 j++; 96 next[i] = j; 97 } 98 else 99 j = next[j]; 100 } 101 /*for(int i = 1; i <= len; i++){ 102 printf("%d ",next[i]); 103 } 104 puts("");*/ 105 }
相关文章推荐
- HDU 3613 Best Reward(拓展KMP算法求解)
- hdu 3948 后缀数组统计不同回文串的个数
- KMP算法---核心就是NEXT数组求解---最长真后缀与前缀相同的字符数
- 【kmp算法next数组求解公共前后缀】Seek the Name, Seek the Fame POJ - 2752
- HDU 3613 Best Reward(求前后缀回文 拓展KMP or Manacher)
- HDU 3613 Best Reward(扩展KMP的应用:回文串判断+扩展KMP模板)
- ural 1297 后缀数组求最长回文串
- HDU 5219 Repeating 后缀数组 + 莫比乌斯函数
- HDU 5558 (后缀数组 二分 RMQ)
- HDU 4898 The Revenge of the Princess’ Knight(后缀数组+二分+暴力)(2014 Multi-University Training Contest 4)
- 字符串相关处理kmp,前缀数,后缀树,后缀数组,最长回文串,最长重复字串,最长非重复字串
- HDU 5030 Rabbit's String 后缀数组
- hdu 5769 后缀数组
- 【BZOJ3654】图样图森破【最长路】【后缀数组】【ST表】【回文串】【LCP】
- [ACM] hdu 5147 Sequence II (树状数组,前缀和,后缀和)
- Manacher算法,回文串及后缀数组问题
- HDU-4622 Reincarnation 后缀数组 | Hash,维护和,扫描
- 【后缀数组】 求字符串的最长回文串
- KMP算法中的next数组求解
- HDU - 3613 Best Reward