题目:hdu3613;
题意:有26字母对应的价值,然后给出以个串,把它分成两段字串,如果字串是回文串,串的价值就是每个字符和,不是就为0。求最大价值。
分析:拓展KMP的应用求回文字串。
#include<iostream> #include<stdio.h> #include<algorithm> #include<string> #include<string.h> using namespace std; const int max_=5e6+10; int extend1[max_],extend2[max_],v[30],w[max_], nex[max_]; void getnext(string str) { int a=0,p=0; int len=str.size(); nex[0]=len; for(int i=1;i<len;i++) { if(i>=p||i+nex[i-a]>=p) { if(i>=p) p=i; while(str[p-i]==str[p]&&p<len) p++; nex[i]=p-i; a=i; } else nex[i]=nex[i-a]; } } void getextend(string str,string mo,int *ex) { int a=0,p=0; getnext(mo); int m=mo.size(); int len=str.size(); for(int i=0;i<len;i++) { if(i>=p||i+nex[i-a]>=p) { if(i>=p) p=i; while(str[p]==mo[p-i]&&p<len&&p-i<m) p++; ex[i]=p-i; a=i; } else ex[i]=nex[i-a]; } } int main() { ios_base::sync_with_stdio(0); cin.tie(0); int t; string S,T; scanf("%d",&t); while(t--) { int max_sum=-1e8; for(int i=0;i<26;i++) { scanf("%d",&v[i]); } cin>>S; int len=S.size(); for(int i=0;i<len;i++) { if(i==0) w[i]=v[S[i]-'a']; else w[i]=w[i-1]+v[S[i]-'a']; } T=S; reverse(T.begin(),T.end()); getextend(S,T,extend1); getextend(T,S,extend2); for(int i=1;i<len;i++) { int sum=0; if(i+extend1[i]==len) sum+=w[len-1]-w[i-1]; if(len-i+extend2[len-i]==len) sum+=w[i-1]; max_sum=max(max_sum,sum); } printf("%d ",max_sum); } }