HDU - 2457
把AC自动机上的状态存进dp状态里,直接暴力转移就可以了
const int N=1e3+10,M=1e7+100,INF=1e9+10;
const int z[10][4]={{-1,0},{-1,1},{0,1},{1,1},{1,0},{1,-1},{0,-1},{-1,-1}};
void chk(int &a,int b){ ((a>b)&&(a=b)); }
int n;
char s[N];
int ch[N];
//AC automation
const int SIZE=N;
int trie[SIZE][4];
int End[SIZE];
int fail[SIZE],cnt;
void clear(){
cnt=0;
memset(End,0,sizeof End);
memset(trie,0,sizeof trie);
memset(fail,0,sizeof fail);
}
void Insert(char *s){
int p=0;
rep(i,0,strlen(s)-1) {
int x=ch[(int)s[i]];
if(!trie[p][x]) trie[p][x]=++cnt;
p=trie[p][x];
}
End[p]=1;
}
void Build() {
static queue <int> que;
rep(i,0,3) if(trie[0][i]) que.push(trie[0][i]);
while(!que.empty()) {
int u=que.front(); que.pop();
End[u]|=End[fail[u]];
rep(i,0,3) {
int &v=trie[u][i];
if(v) {
que.push(v);
fail[v]=trie[fail[u]][i];
} else v=trie[fail[u]][i];
}
}
}
int dp[N][N];
int kase;
int main(){
ch[(int)'A']=0,ch[(int)'T']=1,ch[(int)'C']=2,ch[(int)'G']=3;
while(~scanf("%d",&n) && n) {
clear();
rep(i,1,n) scanf("%s",s),Insert(s);
Build();
scanf("%s",s+1);
int m=strlen(s+1);
memset(dp,63,sizeof dp);
dp[0][0]=0;
rep(i,1,m) {
rep(j,0,cnt) if(!End[j] && dp[i-1][j]<INF) {
int t=ch[(int)s[i]];
rep(k,0,3) chk(dp[i][trie[j][k]],dp[i-1][j]+(k!=t));
}
}
int ans=INF;
rep(j,0,cnt) if(!End[j]) chk(ans,dp[m][j]);
printf("Case %d: %d\n",++kase,ans<INF?ans:-1);
}
}