KMP_Best Reward

大意:把一个字符串分成两串,假如一个字符串是回文串就可以加上它的VALUE,否则它的VALUE为0;

KMP的特点是可以求出前缀与后面的字符串是否匹配,

注意回文串的特点,所以当我们把回文串反转的时候会发现与前面的字符串匹配,

然后将字符串整个反转可以求出后缀的,

利用其特点可以快速判断回文串,

CODE;

#include<cstdio>
#include<cmath>
#include<algorithm>
#include<string.h>
#define N 500008
using namespace std;
typedef long long ll; char s[*N];
int next[*N];
int a[];
int sum[N*],pos[*N],pre[*N]; void get_next(char *s)//NEXT数组
{
next[]=-;
int k=-,i=;
int l=strlen(s);
while (i<l)
{
if (k==-||s[i]==s[k])
{
k++;i++;
next[i]=k;
}
else k=next[k];
}
} int main()
{
int cas;
scanf("%d",&cas); while (cas--)
{
memset(pos,,sizeof(pos));
memset(pre,,sizeof(pre));
for (int i=;i<;i++) scanf("%d",&a[i]);
scanf("%s",s); int len=strlen(s);
for (int i=;i<=len;i++) sum[i]=sum[i-]+a[s[i-]-'a'];//预先处理SUM数组,注意我们把A[I]的值移位了。
s[len]='#';
int k=len,l=len;
while (k) s[++l]=s[--k];//字符串反接在后面
s[++l]='\0';
get_next(s);
int dol=l;
while (next[dol]) {pre[next[dol]]=len+;dol=next[dol];}
for (int i=;i<len;i++)
swap(s[i],s[len++i]); get_next(s);
dol=l;
while (next[dol]) {pos[next[dol]]=len+;dol=next[dol];}; int ans=-;
for (int i=;i<len;i++)//核心代码,计算值
{
int ss=;
if (pre[i]==len+) ss+=sum[i];
if (pos[len-i]==len+) ss+=sum[len]-sum[i];
ans=max(ans,ss);
}
printf("%d\n",ans); }
return ;
}
上一篇:Git 使用问题 - win7 git bash下git pull失败


下一篇:LeetCode算法题-Reverse Linked List(Java实现)