poj 3691 DNA repair(AC自动机+DP)

题目链接:http://poj.org/problem?id=3691

参考博客:http://blog.csdn.net/human_ck/article/details/6577142

AC自动机+DP

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;

struct node
{
	int index;
	node *fail;
	node *next[4];
	int count;
}tire[1005];

int total;
node *root;

char keyword[50];
char str[1005];

node *q[1005];
int head, tail;

int dp[1005][1005];
const int inf = 100000000;

inline int min(int a, int b)
{
	if (a<=b) return a;
	else return b;
}

inline int getcode(char ch)
{
	switch(ch)
	{
	case 'A': return 0;
	case 'T': return 1;
	case 'C': return 2;
	case 'G': return 3;
	}
	return 0;
}

node* new_node()
{
	node *p = &tire[total];
	p->index = total;
	total++;
	p->count = 0;
	p->fail = NULL;
	memset(p->next, 0, sizeof(p->next));
	return p;
}

void insert(node *root, char *s)
{
	node *p = root;
	int i=0, index;
	while(s[i]!='\0')
	{
		index = getcode(s[i]);
		if (p->next[index]==NULL)
			p->next[index] = new_node();
		p = p->next[index];
		i++;
	}
	p->count = 1;
}

void build_ac_automation(node *root)
{
	int i;
	node *temp, *p;
	node *flag;
	root->fail = NULL;
	head = 1;
	tail = 0;
	q[0] = root;
	while(head!=tail)
	{
		temp = q[tail];
		tail++;
		flag = temp;
		p = NULL;
		for (i=0; i<4; i++)
		{
			if (temp->next[i]!=NULL)
			{
				if (temp==root)
					temp->next[i]->fail = root;
				else
				{
					p = temp->next[i];
					temp->next[i]->fail = temp->fail->next[i];
					if (temp->next[i]->fail->count!=0)
						temp->next[i]->count = 1;
				}
				q[head] = temp->next[i];
				head++;
			}
			else
			{
				if (temp==root)
					temp->next[i] = root;
				else
					temp->next[i] = temp->fail->next[i];
			}
		}
	}
}

int solve(char *s)
{
	int len = strlen(s);
	int i,j,k;
	node *p;
	for (i=0; i<=len; i++)
	{
		for (j=0; j<total; j++)
			dp[i][j] = inf;
	}
	dp[0][0] = 0;
	for (i=1; i<=len; i++)
	{
		for (j=0; j<total; j++)
		{
			if (dp[i-1][j]<inf)
			{
				for (k=0; k<4; k++)
				{
					if (tire[j].next[k]->count==0)
					{
						p = tire[j].next[k];
						dp[i][p->index] = min(dp[i][p->index], dp[i-1][j]+(getcode(s[i-1])!=k));
					}
				}
			}
		}
	}
	int ans = inf;
	for (i=0; i<total; i++)
	{
		if (tire[i].count==0 && dp[len][i]<ans)
			ans = dp[len][i];
	}
	if (ans==inf) ans = -1;
	return ans;
}

int main()
{
	int index = 1;
	int n;
	int i;
	while(scanf("%d", &n)!=EOF)
	{
		if (n==0) break;
		total = 0;
		root = new_node();
		for (i=0; i<n; i++)
		{
			scanf("%s", keyword);
			insert(root, keyword);
		}
		build_ac_automation(root);
		scanf("%s", str);
		printf("Case %d: %d\n", index, solve(str));
		index++;
	}
	return 0;
}








你可能感兴趣的:(poj 3691 DNA repair(AC自动机+DP))