大冥神的代码,以后能贴的机会估计就更少了。。。。所以本着有就贴的好习惯,= =。。。。直接贴
#include <bits/stdc++.h> using LL = long long ; #define ALL(v) (v).begin(),(v).end() #define showtime fprintf(stderr,"time = %.15f ",clock() / (double)CLOCKS_PER_SEC) char str[100][11]; int n,m; int weight[100]; const int N = 10 * 100 + 5; int go[N][26],val[N],fail[N],tot; int get_node() { memset(go[tot],-1,sizeof(go[tot])); val[tot] = 0; return tot ++; } int dp[50 + 1][N],pre[50 + 1][N],pc[50 + 1][N]; std::vector<int> order[50 + 1]; void insert(char *s,int w) { int u = 0; for ( ; *s; ++ s) { int c = *s - 'a'; if (go[u][c] == -1) go[u][c] = get_node(); u = go[u][c]; } val[u] += w; } std::string work() { tot = 0; get_node(); for (int i = 0; i < m; ++ i) { insert(str[i],weight[i]); } std::vector<int> vec{0}; fail[0] = -1; for (int I = 0; I < (int)vec.size(); ++ I) { int u = vec[I]; for (int c = 0; c < 26; ++ c) { if (go[u][c] == -1) continue; int v = go[u][c]; int f = fail[u]; while (f != -1 && go[f][c] == -1) f = fail[f]; fail[v] = f == -1 ? 0 : go[f][c]; vec.push_back(v); } } for (int I = (int)vec.size() - 1; I >= 0; -- I) { int u = vec[I]; for (int c = 0; c < 26; ++ c) { int f = u; while (f != -1 && go[f][c] == -1) f = fail[f]; go[u][c] = f == -1 ? -1 : go[f][c]; } for (int f = fail[u]; f != -1; f = fail[f]) { val[u] += val[f]; } } memset(dp,-1,sizeof(dp)); memset(pre,-1,sizeof(pre)); dp[0][0] = 0; for (int i = 0; i <= n; ++ i) { order[i].clear(); } order[0].push_back(0); for (int i = 0; i < n; ++ i) { for (int u : order[i]) { for (int c = 0; c < 26; ++ c) { if (go[u][c] == -1) continue; int v = go[u][c]; dp[i + 1][v] = std::max(dp[i + 1][v],dp[i][u] + val[v]); } } for (int u : order[i]) { for (int c = 0; c < 26; ++ c) { if (go[u][c] == -1) continue; int v = go[u][c]; if (dp[i + 1][v] == dp[i][u] + val[v] && pre[i + 1][v] == -1) { pre[i + 1][v] = u; pc[i + 1][v] = c; order[i + 1].push_back(v); } } } } int ai = 0,au = 0; for (int i = 0; i <= n; ++ i) { for (int u : order[i]) { if (dp[i][u] > dp[ai][au]) { ai = i; au = u; } } } std::string ret; while (ai) { ret.push_back(pc[ai][au] + 'a'); au = pre[ai][au]; -- ai; } std::reverse(ALL(ret)); return ret; } int main() { int cas; scanf("%d",&cas); while (cas--) { scanf("%d%d",&n,&m); for (int i = 0; i < m; ++ i) { scanf("%s",str[i]); } for (int i = 0; i < m; ++ i) { scanf("%d",weight + i); } printf("%s ",work().c_str()); } }