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;
}

posted on 2011-03-15 13:54  宇宙吾心  阅读(669)  评论(0)    收藏  举报

导航