http://acm.hdu.edu.cn/showproblem.php?pid=3613
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 1210 Accepted Submission(s): 495
/**
s[] 先存原字符串,后存扩展后的字符串
p[] p[i] 表示以i为中心的回文串有多长(只记录一边的长度)
sum[] sum[i]表示前i个字符的总价值和
Left[] Left[i] 表示前缀长度为 i 的串是否是回文串
Right[] Right[i] 表示后缀长度为 i 的串是否是回文串
**/
代码:
#include<iostream> #include<stdio.h> #include<string.h> #include<algorithm> using namespace std; #define INF 0x3f3f3f3f #define N 1000007 char s[N]; int Left[N], Right[N], sum[N], p[N]; void Manacher() { int len = strlen(s); int index = 0, MaxLen = 0, i; for(i=2; i<len; i++) { if(MaxLen>i) p[i] = min(p[index*2-i], MaxLen-i); else p[i] = 1; while( s[i-p[i]]==s[i+p[i]]) p[i]++; if(p[i]+i>MaxLen) { MaxLen = p[i] + i; index = i; } if(p[i]==i) Left[p[i]-1] = true; if(p[i]+i==len) Right[p[i]-1] = true; } } int main() { int t; scanf("%d", &t); while(t--) { int a[30], i; memset(Left, 0, sizeof(Left)); memset(Right, 0, sizeof(Right)); for(i=0; i<26; i++) scanf("%d", &a[i]); scanf("%s", s); int len = strlen(s); for(i=1; i<=len; i++) sum[i] = sum[i-1] + a[s[i-1]-‘a‘]; for(i=len; i>=0; i--) { s[i*2+2] = s[i]; s[i*2+1] = ‘#‘; } s[0] = ‘$‘; Manacher(); int ans = -INF; for(i=1; i<len; i++) { int t = 0; if(Left[i]) t += sum[i]; if(Right[len-i]) t += sum[len]-sum[i]; ans = max(ans, t); } printf("%d\n", ans); } return 0; }
(回文串 )Best Reward -- hdu -- 3613
原文:http://www.cnblogs.com/YY56/p/4853437.html