1 #include<iostream>
  2 #include<string>
  3 #include<queue>
  4 #include<cstdio>
  5 #include<cstring>
  6 #define MAXM 26
  7 #define MAXN 1010
  8 #define INF 123456789
  9 using namespace std;
 10 char str[MAXN][MAXM];
 11 string path[MAXM << 1][MAXN];
 12 int size, dp[MAXM << 1][MAXN];
 13 struct Trie {
 14     int fail, cost, next[MAXM];
 15     void Init() {
 16         fail = cost = 0;
 17         memset(next, 0, sizeof(next));
 18     }
 19 };
 20 Trie tree[MAXN];
 21 inline int GET(char ch) {
 22     return ch - 'a';
 23 }
 24 void Insert(char *s, int val) {
 25     int now, t;
 26     for (now = 0; *s; s++) {
 27         t = GET(*s);
 28         if (!tree[now].next[t]) {
 29             tree[++size].Init();
 30             tree[now].next[t] = size;
 31         }
 32         now = tree[now].next[t];
 33     }
 34     tree[now].cost += val;
 35 }
 36 void BFS() {
 37     int now, i, p;
 38     queue<int> q;
 39     q.push(0);
 40     while (!q.empty()) {
 41         now = q.front();
 42         q.pop();
 43         for (i = 0; i < MAXM; i++) {
 44             if (tree[now].next[i]) {
 45                 p = tree[now].next[i];
 46                 q.push(p);
 47                 if (now)
 48                     tree[p].fail = tree[tree[now].fail].next[i];
 49                 tree[p].cost += tree[tree[p].fail].cost;
 50             } else
 51                 tree[now].next[i] = tree[tree[now].fail].next[i];
 52         }
 53     }
 54 }
 55 void DoIt(int n) {
 56     string temp;
 57     int i, j, k, p, ans;
 58     for (i = 0; i <= n; i++) {
 59         for (j = 0; j <= size; j++)
 60             path[i][j].clear();
 61     }
 62     memset(dp, -1, sizeof(dp));
 63     dp[0][0] = ans = 0;
 64     for (i = 1; i <= n; i++) {
 65         for (j = 0; j <= size; j++) {
 66             if (dp[i - 1][j] == -1)
 67                 continue;
 68             for (k = 0; k < MAXM; k++) {
 69                 p = tree[j].next[k];
 70                 if (dp[i][p] < dp[i - 1][j] + tree[p].cost) {
 71                     dp[i][p] = dp[i - 1][j] + tree[p].cost;
 72                     temp.clear();
 73                     temp.push_back('a' + k);
 74                     path[i][p] = path[i - 1][j] + temp;
 75                 } else if (dp[i][p] == dp[i - 1][j] + tree[p].cost) {
 76                     temp.clear();
 77                     temp.push_back('a' + k);
 78                     temp = path[i - 1][j] + temp;
 79                     if (temp < path[i][p])
 80                         path[i][p] = temp;
 81                 }
 82                 ans = max(ans, dp[i][p]);
 83             }
 84         }
 85     }
 86     if (ans == 0)
 87         putchar('\n');
 88     else {
 89         for (i = 1; i <= n; i++) {
 90             for (j = 0; j <= size; j++) {
 91                 if (dp[i][j] == ans) {
 92                     temp = path[i][j];
 93                     break;
 94                 }
 95             }
 96             if (j <= size)
 97                 break;
 98         }
 99         for (j = 0; j <= size; j++) {
100             if (dp[i][j] == ans && path[i][j] < temp)
101                 temp = path[i][j];
102         }
103         cout << temp << endl;
104     }
105 }
106 int main() {
107     int c, i, n, m, val;
108     scanf("%d", &c);
109     while (c--) {
110         size = 0;
111         tree[0].Init();
112         scanf("%d%d", &n, &m);
113         for (i = 1; i <= m; i++)
114             scanf(" %s", str[i]);
115         for (i = 1; i <= m; i++) {
116             scanf("%d", &val);
117             Insert(str[i], val);
118         }
119         BFS();
120         DoIt(n);
121     }
122     return 0;
123 }
posted on 2012-08-05 17:43  DrunBee  阅读(511)  评论(0编辑  收藏  举报