poj 3691
ac自动机+dp
#include<iostream> #include<fstream> using namespace std; struct e{ int p[5]; int end; }trie[1001]; int n,m,K; int hash[300]; int state=1; int f[1001]; void build(char c[]){ int i,j=0,k; for(i=1;;) { if(trie[i].p[hash[c[j]]]==0) trie[i].p[hash[c[j]]]=++state; i=trie[i].p[hash[c[j]]]; j++; if(j>=strlen(c)) break; } trie[i].end=1; } void ac(){ int q[1001]; int l=0,r=0; int i,j,k; for(i=0;i<n;i++) if(trie[1].p[i]) { q[++r]=trie[1].p[i]; f[trie[1].p[i]]=1; } else { trie[1].p[i]=1; } while(l<r){ i=q[++l]; for(j=0;j<n;j++) { if(trie[i].p[j]) { q[++r]=trie[i].p[j]; k=f[i]; while(!trie[k].p[j]) k=f[k]; f[trie[i].p[j]]=trie[k].p[j]; trie[trie[i].p[j]].end|=trie[trie[k].p[j]].end; } } } } int dp[1001][1001]; char c[1004]; void loop(){ int i,j,k,s; dp[0][1]=0; int len=strlen(c); for(s=0;s<len;s++) for(i=1;i<=state;i++) if(trie[i].end) continue; else if(dp[s][i]>=0) { for(j=0;j<n;j++) if(trie[i].p[j]) { k=trie[i].p[j]; if(trie[k].end==0) { if(j==hash[c[s]]) if(dp[s+1][k]==-1) dp[s+1][k]=dp[s][i]; else dp[s+1][k]=min(dp[s+1][k],dp[s][i]); else if(dp[s+1][k]==-1) dp[s+1][k]=dp[s][i]+1; else dp[s+1][k]=min(dp[s+1][k],dp[s][i]+1); } } else { k=f[i]; while(!trie[k].p[j]) k=f[k]; if(!trie[trie[k].p[j]].end) { k=trie[k].p[j]; if(j==hash[c[s]]) if(dp[s+1][k]==-1) dp[s+1][k]=dp[s][i]; else dp[s+1][k]=min(dp[s+1][k],dp[s][i]); else if(dp[s+1][k]==-1) dp[s+1][k]=dp[s][i]+1; else dp[s+1][k]=min(dp[s+1][k],dp[s][i]+1); } } } } void read(){ // ifstream cin("in.txt"); int i,j,k; char c1[30]; while(1){ K++;cin>>m; if(m==0) return ; memset(trie,0,sizeof(trie)); memset(f,0,sizeof(f)); memset(dp,-1,sizeof(dp)); state=1; hash['A']=0; hash['C']=1; hash['G']=2; hash['T']=3; n=4; for(i=1;i<=m;i++) { cin>>c1; build(c1); } ac(); cin>>c; loop(); int ans=-1; int len=strlen(c); for(i=1;i<=state;i++) if(dp[len][i]!=-1) { if(ans==-1) ans=dp[len][i]; else ans=min(ans,dp[len][i]); } printf("Case %d: %d\n",K,ans); } } int main(){ read(); return 0; }