其实是个垃圾题,但是当时我不会AC自动机。
写了几个板题之后这个板子我已经会背了,于是随便写写就1A了。
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <iostream>
using namespace std;
int n, l;
char s[1050];
int w[20];
struct Trie{
int ch[1005][4];
int end[1005];
int fail[1005];
int sz;
int idx(char a){
if(a=='A')return 0;
if(a=='G')return 1;
if(a=='C')return 2;
if(a=='T')return 3;
return 4;
}
int newnode(){
for(int i=0;i<4;i++)ch[sz][i]=-1;
end[sz]=-1;
return sz++;
}
void init(){
sz=0;
newnode();
}
void insert(char s[], int id){
int len=strlen(s);
int u=0;
for(int i=0;i<len;i++){
if(ch[u][idx(s[i])]==-1)ch[u][idx(s[i])]=newnode();
u=ch[u][idx(s[i])];
}
end[u]=id;
}
void build(){
fail[0]=0;
queue<int>q;
for(int i=0;i<4;i++){
if(ch[0][i]==-1){
ch[0][i]=0;
}
else {
fail[ch[0][i]]=0;
q.push(ch[0][i]);
}
}
while(!q.empty()){
int u=q.front();
q.pop();
for(int i=0;i<4;i++){
if(ch[u][i]==-1){
ch[u][i]=ch[fail[u]][i];
}
else {
fail[ch[u][i]]=ch[fail[u]][i];
q.push(ch[u][i]);
}
}
}
}
};
Trie T;
bool dp[2][1050][1050];
int main()
{
while(~scanf("%d%d", &n, &l)){
T.init();
for(int i=1;i<=n;i++){
scanf("%s%d", s, &w[i]);
if((int)strlen(s)>l)continue;
T.insert(s, i-1);
}
T.build();
memset(dp, false, sizeof(dp));
dp[0][0][0]=true;
for(int i=0;i<l;i++){
int u=i%2;
memset(dp[u^1], false, sizeof(dp[u^1]));
for(int j=0;j<T.sz;j++){
for(int k=0;k<(1<<n);k++){
if(dp[u][j][k]){
for(int c=0;c<4;c++){
int to=T.ch[j][c];
int kto=k;
int tmp=to;
while(tmp){
if(T.end[tmp]!=-1){
kto|=(1<<T.end[tmp]);
}
tmp=T.fail[tmp];
}
dp[u^1][to][kto]=true;
}
}
}
}
}
int M=-100000;
for(int i=0;i<T.sz;i++){
for(int j=0;j<(1<<n);j++){
if(dp[l%2][i][j]){
int tmp=0;
for(int k=0;k<n;k++){
if(j&(1<<k)){
tmp+=w[k+1];
}
}
M=max(M, tmp);
}
}
}
if(M<0)printf("No Rabbit after 2012!\n");
else printf("%d\n", M);
}
}