#include<bits/stdc++.h> #include<stdio.h> #include<algorithm> #include<queue> #include<string.h> #include<iostream> #include<math.h> #include<set> #include<map> #include<vector> #include<iomanip> using namespace std; #define ll long long #define ull unsigned long long #define pb push_back #define FOR(a) for(int i=1;i<=a;i++) const int inf=0x3f3f3f3f; const int maxn=1e6+7; const long long mod=1e9+7; const int sigma=4; ll ans; char s[1111]; int dp[1111][1111];//想转移到长度i状态j,最少修改次数 struct automata{ int ch[maxn][sigma]; int val[maxn]; int f[maxn]; int sz; int idx(char x){if(x=='A')return 0;if(x=='C')return 1; if(x=='G')return 2;return 3;} int newnode(){ memset(ch[sz],0,sizeof(ch[sz])); f[sz]=val[sz]=0; return sz++; } void init(){ memset(val,0,sizeof(val)); sz=0; newnode(); } void insert(char *s,int v){ int u=0; int len=strlen(s); for(int i=0;i<len;i++){ int id=idx(s[i]);//s[i]-'a'; if(!ch[u][id])ch[u][id]=newnode(); u=ch[u][id]; } val[u]=v; } void build(){ queue<int>q; q.push(0); while(!q.empty()){ int u=q.front();q.pop(); if(val[f[u]]){ val[u]=val[f[u]]; } for(int i=0;i<sigma;i++){ int v=ch[u][i]; if(!v)ch[u][i]=ch[f[u]][i]; else q.push(v); if(u&&v)f[v]=ch[f[u]][i]; } } } void solve(){ int len=strlen(s); for(int i=0;i<=len;i++)for(int j=0;j<sz;j++)dp[i][j]=inf; dp[0][0]=0; for(int i=0;i<len;i++){ for(int j=0;j<sz;j++){ if(dp[i][j]!=inf){ //状态可达 for(int k=0;k<4;k++){ if(val[ch[j][k]])continue;//病毒串,不转移 int tmp; if(idx(s[i])==k)tmp=dp[i][j];//不改转移 else tmp=dp[i][j]+1; //改一个转移 dp[i+1][ch[j][k]]=min(dp[i+1][ch[j][k]],tmp); } } } } int ans=inf; for(int i=0;i<sz;i++)ans=min(dp[len][i],ans); if(ans==inf)printf("-1 "); else printf("%d ",ans); } }ac; char buf[60]; int n; int main(){ int kase=0; while(~scanf("%d",&n) && n){ ac.init(); for(int i=1;i<=n;i++){ scanf("%s",buf); ac.insert(buf,1); } scanf("%s",s); ac.build(); printf("Case %d: ",++kase); ac.solve(); } }基本上自动机DP的状态关系算是学到一些了,搞搞别的吧