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

来源:互联网 发布:淘宝助理如何描述宝贝 编辑:程序博客网 时间:2024/05/18 01:09

题目链接: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;elsetemp->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;}








0 0