dp[i][j]表示长度为i在节点J的时候的权值最大值,根据trie树转移一下就行,需要每次都取最小的,所以需要另开一数组保存字典序最小的状态。
1 #include <iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<stdlib.h> 6 #include<vector> 7 #include<cmath> 8 #include<queue> 9 #include<set> 10 #include<string> 11 using namespace std; 12 #define N 1105 13 #define LL long long 14 #define INF 0xfffffff 15 const double eps = 1e-8; 16 const double pi = acos(-1.0); 17 const double inf = ~0u>>2; 18 const int child_num = 26; 19 char vir[110][15]; 20 string o[55][N]; 21 class AC 22 { 23 private: 24 int ch[N][child_num]; 25 int fail[N]; 26 int Q[N]; 27 int val[N]; 28 int sz; 29 int id[128]; 30 int dp[55][N]; 31 char s[N]; 32 public: 33 void init() 34 { 35 fail[0] = 0; 36 for(int i = 0 ; i < child_num ;i++) 37 id[i+'a'] = i; 38 } 39 void reset() 40 { 41 memset(ch[0],0,sizeof(ch[0])); 42 memset(val,0,sizeof(val)); 43 sz = 1; 44 } 45 void insert(char *a,int key) 46 { 47 int p = 0; 48 for(; *a ; a++) 49 { 50 int d= id[*a]; 51 if(ch[p][d]==0) 52 { 53 memset(ch[sz],0,sizeof(ch[sz])); 54 s[sz] = *a; 55 ch[p][d] = sz++; 56 } 57 p = ch[p][d]; 58 } 59 val[p] = key; 60 } 61 void construct() 62 { 63 int i,head=0,tail = 0; 64 for(i = 0; i < child_num ;i++) 65 { 66 if(ch[0][i]) 67 { 68 fail[ch[0][i]] = 0; 69 Q[tail++] = ch[0][i]; 70 } 71 } 72 while(head!=tail) 73 { 74 int u = Q[head++]; 75 val[u]+=val[fail[u]]; 76 for(i = 0; i < child_num ; i++) 77 { 78 if(ch[u][i]) 79 { 80 fail[ch[u][i]] = ch[fail[u]][i]; 81 Q[tail++] = ch[u][i]; 82 } 83 else ch[u][i] = ch[fail[u]][i]; 84 } 85 } 86 } 87 void work(int n) 88 { 89 int i,j,g; 90 for(i = 0 ; i <= n ;i++) 91 for(j = 0 ;j < sz ; j++) 92 { 93 dp[i][j] = -INF; 94 o[i][j].clear(); 95 } 96 dp[0][0] = 0; 97 for(i = 0; i < n ;i++) 98 { 99 for(j = 0 ; j < sz ; j++) 100 for(g = 0 ; g < child_num ; g++) 101 { 102 int tv = dp[i][j]+val[ch[j][g]]; 103 if(dp[i+1][ch[j][g]] <= tv) 104 { 105 if(dp[i+1][ch[j][g]]<tv||o[i+1][ch[j][g]]>o[i][j]+char(g+'a')) 106 o[i+1][ch[j][g]] = o[i][j]+char(g+'a'); 107 dp[i+1][ch[j][g]] = dp[i][j]+val[ch[j][g]]; 108 } 109 } 110 } 111 int ans = 0,y=0,x=0; 112 for(i = 0 ; i <=n ;i++) 113 for(j =0 ;j < sz ; j++) 114 { 115 if(ans<=dp[i][j]) 116 { 117 if(ans<dp[i][j]||(y==i&&o[i][j]<o[i][x])) 118 { 119 ans = dp[i][j]; 120 y = i; 121 x = j; 122 } 123 } 124 } 125 g = 0; 126 if(ans==0) puts(""); 127 else 128 cout<<o[y][x]<<endl; 129 } 130 }ac; 131 int main() 132 { 133 int n,i,m,t; 134 ac.init(); 135 cin>>t; 136 while(t--) 137 { 138 scanf("%d%d",&n,&m); 139 ac.reset(); 140 for(i = 1;i <= m ;i++) 141 scanf("%s",vir[i]); 142 for(i = 1; i <= m ;i++) 143 { 144 int v; 145 scanf("%d",&v); 146 ac.insert(vir[i],v); 147 } 148 ac.construct(); 149 ac.work(n); 150 } 151 return 0; 152 }