传送门

题意:

  国王为了犒劳立下战功的大将军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代码:
 #include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define INF 0x3f3f3f3f
#define lowbit(x) (x&-x)
#define mem(a,b) memset(a,b,sizeof(a))
const int maxn=5e5+; int val[];
char s[*maxn];
char temp[maxn];
int radius[*maxn];
int sum[*maxn];
void Trans()
{
int len=strlen(s);
strcpy(temp,s);
for(int i=;i < len;++i)
{
s[*i]='#';
s[*i+]=temp[i];
}
s[*len]='#';
s[*len+]='\0';
}
void Manacher()
{
mem(radius,);
int len=strlen(s);
int R=;
int K=;
radius[]=;
for(int i=;i < len;++i)
{
int cnt=;
if(i >= R)
{
while(i+cnt < len && i-cnt >= && s[i+cnt] == s[i-cnt])
cnt++;
radius[i]=cnt;
if(i+cnt- > R)
{
R=i+cnt-;
K=i;
}
}
else
{
int j=K-(i-K);
if(i+radius[j]- != R)
radius[i]=min(R-i+,radius[j]);
else
{
cnt=R-i+;
while(i-cnt >= && i+cnt < len && s[i-cnt] == s[i+cnt])
cnt++;
radius[i]=cnt;
if(i+cnt- > R)
{
R=i+cnt-;
K=i;
}
}
}
}
}
int Solve()
{
Trans();//预处理字符串s
Manacher(); int len=strlen(s);
sum[]=;
for(int i=;i < len;++i)//前缀和
sum[i]=sum[i-]+(s[i] == '#' ? :val[s[i]-'a']); int ans=-INF;
for(int i=;i < len-;i+=)
{
int cnt=;
int x=(i+)>>;//[0,i+1]的中点坐标
if(radius[x] == x+)//判断[0,i]是否构成回文子串
cnt += sum[i]; int y=(len+i)>>;//[i+1,len-1]的中点坐标
if(radius[y] == len-y)//判断[i+1,len-1]是否构成回文子串
cnt += sum[len-]-sum[i];
ans=max(ans,cnt);
}
return ans;
}
int main()
{
// freopen("C:/Users/hyacinthLJP/Desktop/stdin/contest","r",stdin);
int test;
scanf("%d",&test);
while(test--)
{
for(int i=;i < ;++i)
scanf("%d",val+i);
scanf("%s",s);
printf("%d\n",Solve());
}
return ;
}

hdu 3613"Best Reward"(Manacher算法)的更多相关文章

  1. HDU 3613 Best Reward(KMP算法求解一个串的前、后缀回文串标记数组)

    题目链接: https://cn.vjudge.net/problem/HDU-3613 After an uphill battle, General Li won a great victory. ...

  2. HDU 3613 Best Reward 正反两次扩展KMP

    题目来源:HDU 3613 Best Reward 题意:每一个字母相应一个权值 将给你的字符串分成两部分 假设一部分是回文 这部分的值就是每一个字母的权值之和 求一种分法使得2部分的和最大 思路:考 ...

  3. HDU 3613 Best Reward(manacher求前、后缀回文串)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3613 题目大意: 题目大意就是将字符串s分成两部分子串,若子串是回文串则需计算价值,否则价值为0,求分 ...

  4. HDU - 3613 Best Reward(manacher或拓展kmp)

    传送门:HDU - 3613 题意:给出26个字母的价值,然后给你一个字符串,把它分成两个字符串,字符串是回文串才算价值,求价值最大是多少. 题解:这个题可以用马拉车,也可以用拓展kmp. ①Mana ...

  5. hdu 3613 Best Reward

    After an uphill battle, General Li won a great victory. Now the head of state decide to reward him w ...

  6. HDU3613 Best Reward —— Manacher算法 / 扩展KMP + 枚举

    题目链接:https://vjudge.net/problem/HDU-3613 Best Reward Time Limit: 2000/1000 MS (Java/Others)    Memor ...

  7. HDU 3613 Best Reward(拓展KMP算法求解)

    题目链接: https://cn.vjudge.net/problem/HDU-3613 After an uphill battle, General Li won a great victory. ...

  8. hdu 3613 Best Reward (manachar算法)

    Best Reward Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Prob ...

  9. HDU 3613 Best Reward ( 拓展KMP求回文串 || Manacher )

    题意 : 给个字符串S,要把S分成两段T1,T2,每个字母都有一个对应的价值,如果T1,T2是回文串,那么他们就会有一个价值,这个价值是这个串的所有字母价值之和,如果不是回文串,那么这串价值就为0.问 ...

随机推荐

  1. SWT 几个sample网站

    https://www.programcreek.com/java-api-examples/org.eclipse.swt.custom.ScrolledComposite https://o7pl ...

  2. Ajax 长轮询

    长轮询:客户端向服务器发送Ajax请求,服务器接到请求后hold住连接,直到有新消息才返回响应信息并关闭连接,客户端处理完响应信息后再向服务器发送新的请求. 优点:在无消息的情况下不会频繁的请求. 缺 ...

  3. c++中结构体sort()排序

    //添加函数头 #include <algorithm> //定义结构体Yoy typedef struct { double totalprice;         //总价 doubl ...

  4. mysql中count的注意事项

    1.count()函数是用来统计表中记录的一个函数,返回匹配条件的行数. 2.count()语法: (1)count(*)---包括所有列,返回表中的记录数,相当于统计表的行数,在统计结果的时候,不会 ...

  5. [51Nod 1584] 加权约数和

    Description 在整理以前的试题时,他发现了这样一道题目:"求 \(\sum\sigma(i)\),其中 \(1≤i≤N\),\(σ(i)\) 表示 \(i\) 的约数之和.&quo ...

  6. linux-shell系列5-统计

    #!/bin/bashshow=$(service --status-all 2>/dev/null | grep -E "is running|正在运行"|awk '{pr ...

  7. Codeforces Round #467 Div. 1

    B:显然即相当于能否找一条有长度为奇数的路径使得终点出度为0.如果没有环直接dp即可.有环的话可以考虑死了的spfa,由于每个点我们至多只需要让其入队两次,复杂度变成了优秀的O(kE).事实上就是拆点 ...

  8. BZOJ2434 [NOI2011] 阿狸的打字机 【树链剖分】【线段树】【fail树】【AC自动机】

    题目分析: 画一下fail树,就会发现就是x的子树中属于y路径的,把y剖分一下,用线段树处理 $O(n*log^2 n)$. 代码: #include<bits/stdc++.h> usi ...

  9. Codeforces962F Simple Cycles Edges 【双连通分量】【dfs树】

    题目大意: 给出一个无向图,问有哪些边只属于一个简单环. 题目分析: 如果这道题我们掌握了点双连通分量,那么结论会很显然,找到每个点双,如果一个n个点的点双正好由n条边构成,那么这些边都是可以的. 这 ...

  10. shelve 模块

    shelve 模块概述:   shelve是python的自带model.   可以直接通过import shelve来引用.   shelve类似于一个存储持久化对象的持久化字典,即字典文件.   ...