题意:
中文
思路:
建立 AC自动机 时记录下每个子串的长度dep
对母串进行匹配时
ans[i] 代表匹配到母串位置 i 的最大的答案
状态转移为:
ans[i]=max(ans[i],ans[i-dep[rt]]+val[rt])
代码:
ans[i]=max(ans[i],ans[i-dep[rt]]+val[rt]);#include <iostream>
#include <queue>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
using namespace std;
const int MAXN=1e3+7;
int n,cnt;
int ans[MAXN*MAXN];
int son[MAXN*MAXN][27];
int fail[MAXN*MAXN];
int val[MAXN*MAXN];
int dep[MAXN*MAXN];
void newnode(){
cnt++;
for(int i=0;i<26;i++) son[cnt][i]=0;
val[cnt]=0;
}
void ini(){
cnt=0;
dep[1]=0;
newnode();
fail[1]=0;
}
void insert(){
string str;
int v;
cin>>str>>v;
int rt=1;
int len=str.size();
for(int i=0;i<len;i++){
int ch=str[i]-'a';
if(!son[rt][ch]) newnode(),son[rt][ch]=cnt,dep[cnt]=dep[rt]+1;
rt=son[rt][ch];
}
val[rt]=v;
}
void get_fail(){
queue <int> que;
que.push(1);
while(!que.empty()){
int now=que.front();
que.pop();
for(int i=0;i<26;i++){
if(son[now][i]){
int pos=fail[now];
while(pos){
if(son[pos][i]){
fail[son[now][i]]=son[pos][i];
break;
}
pos=fail[pos];
}
if(!pos) fail[son[now][i]]=1;
que.push(son[now][i]);
}
}
}
}
int query(){
string str;cin>>str;
int len=str.size();
int rt=1;
for(int i=0;i<len;i++){
ans[i]=0;
if(i>0) ans[i]=ans[i-1];
int ch=str[i]-'a';
while(1){
if(rt==0){
rt=1;
break;
}
if(son[rt][ch]){
rt=son[rt][ch];
if(val[rt]){
ans[i]=max(ans[i],ans[i-dep[rt]]+val[rt]);
}
break;
}
rt=fail[rt];
}
}
return *max_element(ans,ans+len);
}
int main(){
ios::sync_with_stdio(false);
//freopen("data.in","r",stdin);
//freopen("out.txt","w",stdout);
while(cin>>n){
ini();
for(int i=0;i<n;i++) insert();
get_fail();
cout<<query()<<endl;
}
}