http://acm.hdu.edu.cn/showproblem.php?pid=2296
2 7 2 love ever 5 5 5 1 ab 5
lovever ababHintSample 1: weight(love) = 5, weight(ever) = 5, so weight(lovever) = 5 + 5 = 10 Sample 2: weight(ab) = 2 * 5 = 10, so weight(abab) = 10
/** hdu2296 AC自动机+DP 题目大意:给出m个模式串,每个串有一定的分值,构造一个长度不超过n的串,使得分值最大,输出长度最小,字典序最小的串 解题思路:dp[i][j]表示长度为i的时候,在Trie上的第j个结点时的最大分值,str[i][j]表示状态(i,j)时的字典序最小的串。 */ #include <stdio.h> #include <string.h> #include <iostream> #include <algorithm> #include <queue> using namespace std; const int INF=0x3f3f3f3f; int a[110]; int dp[55][1110]; char str[55][1110][55]; bool cmp(char *s1,char *s2) { int len1=strlen(s1); int len2=strlen(s2); if(len1!=len2) return len1<len2; return strcmp(s1,s2)<0; } struct Trie { int next[1110][26],fail[1110],end[1110]; int root,L; int newnode() { for(int i=0; i<26; i++) next[L][i]=-1; end[L++]=-1; return L-1; } void init() { L=0; root=newnode(); } void insert(char *buf,int id) { int len=strlen(buf); int now=root; for(int i=0; i<len; i++) { if(next[now][buf[i]-'a']==-1) next[now][buf[i]-'a']=newnode(); now=next[now][buf[i]-'a']; } end[now]=id; } void build() { queue<int>Q; fail[root]=root; for(int i=0; i<26; i++) { if(next[root][i]==-1) next[root][i]=root; else { fail[next[root][i]]=root; Q.push(next[root][i]); } } while(!Q.empty()) { int now=Q.front(); Q.pop(); for(int i=0; i<26; i++) { if(next[now][i]==-1) next[now][i]=next[fail[now]][i]; else { fail[next[now][i]]=next[fail[now]][i]; Q.push(next[now][i]); } } } } void solve(int n) { for(int i=0; i<=n; i++) { for(int j=0; j<L; j++) { dp[i][j]=-INF; } } dp[0][0]=0; char ans[55]; memset(str[0][0],0,sizeof(str[0][0])); memset(ans,0,sizeof(ans)); int maxx=0; char tmp[55]; for(int i=0; i<n; i++) { for(int j=0; j<L; j++) { if(dp[i][j]>=0) { strcpy(tmp,str[i][j]); int len=strlen(tmp); for(int k=0; k<26; k++) { int nxt=next[j][k]; tmp[len]='a'+k; tmp[len+1]=0; int tt=dp[i][j]; if(end[nxt]!=-1) tt+=a[end[nxt]]; if(dp[i+1][nxt]<tt||(dp[i+1][nxt]==tt&&cmp(tmp,str[i+1][nxt]))) { dp[i+1][nxt]=tt; strcpy(str[i+1][nxt],tmp); if(tt>maxx||(tt==maxx&&cmp(tmp,ans))) { maxx=tt; strcpy(ans,tmp); } } } } } } printf("%s\n",ans); } } ac; char buf[60]; int main() { int T; int n,m; scanf("%d",&T); while(T--) { scanf("%d%d",&n,&m); ac.init(); for(int i=0; i<m; i++) { scanf("%s",buf); ac.insert(buf,i); } for(int i=0; i<m; i++) { scanf("%d",&a[i]); } ac.build(); ac.solve(n); } return 0; }