题意:
国王为了犒劳立下战功的大将军Li,决定奖给Li一串项链,这个项链一共包含26中珠子"a~z",每种珠子都有
相应的价值(-100~100),当某个项链可以构成回文时,那么这个项链的价值就是每个珠子价值的加和,如果
构不成,那么这个项链的价值就为0;
求如何将国王奖赏的一串项链拆成价值加和最大的两串项链,求出这个最大价值。
题解:
本来我是在找有关拓展KMP的相关题目的,百度到一大牛的博客(“扩展KMP题目”),当做到第二个题目的时候,
思来想去,就是没找到其和拓展KMP的联系,然后,感觉可以用Manacher算法,刷刷刷撸了个Manacher的代码
提交,AC,所以,我暂且谈谈如何用Manacher算法解这道题;
①首先将项链串s[]预处理(了解Manacher算法就理解啥意思了);
②准备一个数组sum[],sum[ i ]:预处理后的数组中前 i 个字符对应的价值的加和,'#'当作0;
③使用Manacher算法求解出回文半径数组radius[];
④假设从 i 位置切割项链,将项链分成[ 0,i ],[ i,len-1 ]两串,分别求解对应的总价值,令ans=max{从i位置分割的总价值}
AC代码:
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 using namespace std; 5 #define INF 0x3f3f3f3f 6 #define lowbit(x) (x&-x) 7 #define mem(a,b) memset(a,b,sizeof(a)) 8 const int maxn=5e5+50; 9 10 int val[26]; 11 char s[2*maxn]; 12 char temp[maxn]; 13 int radius[2*maxn]; 14 int sum[2*maxn]; 15 void Trans() 16 { 17 int len=strlen(s); 18 strcpy(temp,s); 19 for(int i=0;i < len;++i) 20 { 21 s[2*i]='#'; 22 s[2*i+1]=temp[i]; 23 } 24 s[2*len]='#'; 25 s[2*len+1]='