| #include<iostream> #include<cstring> #include<cstdlib> #include<cstdio> #include<queue> #include<cmath> #include<algorithm> using namespace std; const int maxn=1024+10, DEF=0x8f8f8f8f; int n, m, rt, tot, val[maxn]; bool f[2][maxn][maxn]; struct node { 	int nxt[4], fail, st; 	void Init() 	{ 		fail=st=0; 		memset(nxt, 0, sizeof nxt); 		return ; 	} }tr[maxn]; int getch(char c) { 	if(c=='A')	return 0; 	if(c=='T')	return 1; 	if(c=='G')	return 2; 	return 3; } void Insert(int rt, int k, char *ch) { 	for(int i=0, len=strlen(ch), cur; i<len; i++) 	{ 		cur=getch(ch[i]); 		if(!tr[rt].nxt[cur]) 		{ 			tr[++tot].Init(); 			tr[rt].nxt[cur]=tot; 		} 		rt=tr[rt].nxt[cur]; 	} 	tr[rt].st|=(1<<k); 	return ; } void Build(int rt) { 	queue<int> q; 	q.push(rt); 	while(!q.empty()) 	{ 		int now=q.front(), p=0; 		q.pop(); 		for(int i=0; i<4; i++) 		{ 			if(!tr[now].nxt[i])	tr[now].nxt[i]=tr[tr[now].fail].nxt[i]; 			else 			{ 				p=tr[now].nxt[i]; 				q.push(p); 				if(now)	tr[p].fail=tr[tr[now].fail].nxt[i]; 				tr[p].st|=tr[tr[p].fail].st; 			} 		} 	} 	return ; } int Cal(int st) { 	int cnt=0; 	for(int i=0; i<n; i++) if(st&(1<<i))	cnt+=val[i]; 	return cnt; } int Work() { 	memset(f, 0, sizeof f); 	f[0][0][0]=1; 	 	int lim=1<<n, u=0, ans=DEF; 	for(int i=1; i<=m; i++) 	{ 		u^=1; 		memset(f[u], 0, sizeof f[u]); 		for(int j=0; j<=tot; j++) 			for(int k=0; k<lim; k++) 				for(int h=0; h<4; h++) 					f[u][tr[j].nxt[h]][k|tr[tr[j].nxt[h]].st]|=f[u^1][j][k]; 	} 	for(int i=0; i<=tot; i++) 		for(int j=0; j<lim; j++) if(f[u][i][j]) 			ans=max(ans, Cal(j)); 	return ans; } int main() { 	while(scanf("%d%d", &n,  &m)!=EOF) 	{ 		rt=0, tot=0; 		tr[rt].Init(); 		 		char s[maxn]; 		for(int i=0; i<n; i++) 		{ 			scanf("%s%d", s, &val[i]); 			Insert(rt, i, s); 		} 		Build(rt); 		 		int ans=Work(); 		ans<0 ? printf("No Rabbit after 2012!\n") : printf("%d\n", ans); 	} 	return 0; }
 |