hdu2457---DNA repair(AC自动机+dp)
Problem Description You are to help the biologists to repair a DNA by changing least number of characters. Input The last test case is followed by a line containing one zeros. Output Sample Input 2 AAA AAG AAAG 2 A TG TGAATG 4 A G C T AGT 0 Sample Output Case 1: 1 Case 2: 4 Case 3: ⑴ Source Recommend 设每个模式串结尾所在的节点为危险节点,明显在AC自动机上,如果1个节点的fail指针指向的那个节点是危险节点,那末这个节点是危险节点,由于它们是后缀关系 /*************************************************************************
> File Name: hdu2457.cpp
> Author: ALex
> Mail: zchao1995@gmail.com
> Created Time: 2015年03月05日 星期4 14时29分23秒
************************************************************************/
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <vector>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const double pi = acos(-1);
const int inf = 0x3f3f3f3f;
const double eps = 1e⑴5;
typedef long long LL;
typedef pair <int,int> PLL;
const int MAX_NODE = 2010;
const int CHILD_NUM = 4;
int dp[1010][MAX_NODE];
struct AC_Automation
{
int next[MAX_NODE][CHILD_NUM];
int fail[MAX_NODE];
int end[MAX_NODE];
int root,L;
int ID (char c)
{
if (c == 'A')
{
return 0;
}
if (c == 'G')
{
return 1;
}
if (c == 'C')
{
return 2;
}
if (c == 'T')
{
return 3;
}
}
int newnode ()
{
for (int i = 0; i < CHILD_NUM; ++i)
{
next[L][i] = -1;
}
end[L++] = 0;
return L - 1;
}
void init ()
{
L = 0;
root = newnode ();
}
void Build_Trie (char buf[])
{
int now = root;
int len = strlen (buf);
for (int i = 0; i < len; ++i)
{
if (next[now][ID(buf[i])] == -1)
{
next[now][ID(buf[i])] = newnode();
}
now = next[now][ID(buf[i])];
}
end[now] = 1;
}
void Build_AC ()
{
queue <int> qu;
fail[root] = root;
for (int i = 0; i < CHILD_NUM; ++i)
{
if (next[root][i] == -1)
{
next[root][i] = root;
}
else
{
fail[next[root][i]] = root;
qu.push (next[root][i]);
}
}
while (!qu.empty())
{
int now = qu.front();
qu.pop();
if (end[fail[now]])
{
end[now] = 1;
}
for (int i = 0; i < CHILD_NUM; ++i)
{
if (next[now][i] == -1)
{
next[now][i] = next[fail[now]][i];
}
else
{
fail[next[now][i]] = next[fail[now]][i];
qu.push (next[now][i]);
}
}
}
}
void solve(char buf[])
{
memset (dp,inf,sizeof(dp));
dp[0][0] = 0;
int len = strlen (buf);
for (int i = 0; i < len; ++i)
{
for (int j = 0; j < L; ++j)
{
if (dp[i][j] < inf)
{
for (int k = 0; k < 4; ++k)
{
int now = next[j][k];
if (end[now])
{
continue;
}
int use = dp[i][j];
if (k != ID(buf[i]))
{
++use;
}
dp[i + 1][now] = min (dp[i + 1][now],use);
}
}
}
}
int ans = inf;
for (int i = 0; i < L; ++i)
{
ans = min (ans,dp[len][i]);
}
printf("%d
",ans >= inf ? -1 : ans);
}
}AC;
char buf[1010];
int main ()
{
int n;
int icase = 1;
while (~scanf("%d",&n),n)
{
printf("Case %d: ",icase++);
AC.init();
for (int i = 1; i <= n; ++i)
{
scanf("%s",buf);
AC.Build_Trie (buf);
}
AC.Build_AC();
scanf("%s",buf);
AC.solve (buf);
}
return 0;
} (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |