这道题就是普通的求单词贡献最大,然后让你输出这个单词是多少,wa了老半天,最后调了好久,比较字符串先比较长度,长度短的优先,然后再比较字典序
#include<bits/stdc++.h>
using namespace std;
using LL = int64_t;
const int maxnode=1e6+5;
const int sigma_size=27;
char s[maxnode];
struct Node {
int son[sigma_size];
int val,fail;
}ch[maxnode];
struct NODE{
char s[105];
int num;
}node[105];
int dp[55][1005],n,m;
string path[55][1005];
bool check(string x,string y) {
if(x.length()>y.length()) return true;
if(x.length()==y.length()&&x>y) return true;
return false;
}
struct AC {
int sz=1;
queue<int>Q;
void init(int x) {ch[x].fail=ch[x].val=0;memset(ch[x].son,0,sizeof(ch[x].son));}
int idx(char c) {return c-'a';}
void insert(char s[],int v) {
int u=0,n=strlen(s);
for(int i=0;i<n;i++) {
int c=idx(s[i]);
if(!ch[u].son[c]) {
init(sz);
ch[u].son[c]=sz++;
}
u=ch[u].son[c];
}
ch[u].val=v;
}
void build() {
for(int i=0;i<26;i++) if(ch[0].son[i]) Q.push(ch[0].son[i]);
while(!Q.empty()) {
int now=Q.front();Q.pop();
int fail=ch[now].fail;
for(int i=0;i<26;i++) {
int nxt=ch[now].son[i];
if(nxt) {
ch[nxt].fail=ch[fail].son[i];
Q.push(nxt);
}
else ch[now].son[i]=ch[fail].son[i];
//if(ch[ch[now].son[i]].val)ch[ch[now].son[i]].val+=ch[ch[ch[now].fail].son[i]].val;
}
}
}
void solve() {
//for(int i=0;i<sz;i++) cout<<ch[i].val<<endl;
for(int i=0;i<=n;i++) {
for(int j=0;j<sz;j++) {
dp[i][j]=-1;path[i][j].clear();
}
}
dp[0][0]=0;
for(int i=0;i<=n;i++) {
for(int j=0;j<sz;j++) {
for(int k=0;k<26;k++) {
if(dp[i][j]==-1) continue;
if(dp[i][j]+ch[ch[j].son[k]].val>dp[i+1][ch[j].son[k]]) {
dp[i+1][ch[j].son[k]]=dp[i][j]+ch[ch[j].son[k]].val;
path[i+1][ch[j].son[k]]=path[i][j]+(char)(k+'a');
//cout<<path[i+1][ch[j].son[k]]<<" "<<dp[i+1][ch[j].son[k]]<<endl;
}
else if(dp[i][j]+ch[ch[j].son[k]].val==dp[i+1][ch[j].son[k]]&&check(path[i+1][ch[j].son[k]],path[i][j]+(char)(k+'a'))) {
dp[i+1][ch[j].son[k]]=dp[i][j]+ch[ch[j].son[k]].val;
path[i+1][ch[j].son[k]]=path[i][j]+(char)(k+'a');
//cout<<path[i+1][ch[j].son[k]]<<" "<<dp[i+1][ch[j].son[k]]<<endl;
}
}
}
}
int x=0,y=0,maxs=0;
for(int i=0;i<=n;i++) {
for(int j=0;j<sz;j++) {
if(dp[i][j]>dp[x][y]) x=i,y=j;
else if(dp[i][j]==dp[x][y]&&check(path[x][y],path[i][j])) x=i,y=j;
//cout<<path[i][j]<<"\n";
}
//cout<<endl;
}
if(dp[x][y]<=0) cout<<"\n";
else cout<<path[x][y]<<"\n";
}
}ans;
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);cout.tie(0);
int T;cin>>T;
while(T--) {
ans.init(0);ans.sz=1;
cin>>n>>m;
for(int i=1;i<=m;i++)cin>>node[i].s;
for(int i=1;i<=m;i++) {
cin>>node[i].num;
ans.insert(node[i].s,node[i].num);
}
ans.build();ans.solve();
}
return 0;
}