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;
}
浙公网安备 33010602011771号