Time Limit: 5000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 2004 Accepted Submission(s): 1085
/*
hdu 2457 AC自动机+dp
给你n个子串和一个主串. 对主串最少修改多少次后使其不包含子串
通过AC自动机能够处理出 一个状态转移图
用dp[i][j]表示长度为i,当前位置为j的最小修改数. nex[j][k] 状态k的节点编号
如果当前位置与主串相同则不需要修改, 否则 +1
而且通过ed数组我们判断当前是否已经走到任意子串的结尾.
那么 dp[i][nex[j][k]] = min(dp[i][nex[j][k]],dp[i-1][j] + (k == str[i]? 0:i));
hhh-2016-04-24 11:23:59
*/
#include <iostream>
#include <vector>
#include <cstring>
#include <string>
#include <cstdio>
#include <queue>
#include <algorithm>
#include <functional>
#include <map>
using namespace std;
#define lson (i<<1)
#define rson ((i<<1)|1)
typedef unsigned long long ll;
typedef unsigned int ul;
const int INF = 0x3f3f3f3f;
int tot;
int dp[2][1010];
//struct Matrix
//{
// int len;
// int ma[1010][1010];
// Matrix() {}
// Matrix(int L)
// {
// len = L;
// }
//};
struct Tire
{
int nex[1010][4],fail[1010],ed[1010];
int root,L;
int newnode()
{
for(int i = 0; i < 4; i++)
nex[L][i] = -1;
ed[L++] = 0;
return L-1;
}
void ini()
{
L = 0,root = newnode();
}
int cal(char ch)
{
if(ch == ‘A‘)
return 0;
else if(ch == ‘C‘)
return 1;
else if(ch == ‘G‘)
return 2;
else if(ch == ‘T‘)
return 3;
}
void inser(char buf[])
{
int len = strlen(buf);
int now = root;
for(int i = 0; i < len; i++)
{
int ta = cal(buf[i]);
if(nex[now][ta] == -1)
nex[now][ta] = newnode();
now = nex[now][ta];
}
ed[now] ++;
}
void build()
{
queue<int >q;
fail[root] = root;
for(int i = 0; i < 4; i++)
if(nex[root][i] == -1)
nex[root][i] = root;
else
{
fail[nex[root][i]] = root;
q.push(nex[root][i]);
}
while(!q.empty())
{
int now = q.front();
q.pop();
if(ed[fail[now]])
ed[now] = 1;
for(int i = 0; i < 4; i++)
{
if(nex[now][i] == -1)
nex[now][i] = nex[fail[now]][i];
else
{
fail[nex[now][i]] = nex[fail[now]][i];
q.push(nex[now][i]);
}
}
}
}
// Matrix to_mat()
// {
// Matrix mat(L);
// memset(mat.ma,0,sizeof(mat.ma));
// for(int i = 0; i < L; i++)
// {
// for(int j = 0; j < 4; j++)
// {
// if(!ed[nex[i][j]])
// mat.ma[i][nex[i][j]] ++;
// }
// }
// return mat;
// }
};
//Matrix mat;
Tire ac;
char str[1100];
char buf[22];
int main()
{
int n;
int cas = 1;
while(scanf("%d",&n) != EOF && n)
{
ac.ini();
for(int i = 1; i <= n; i++)
{
scanf("%s",buf);
ac.inser(buf);
}
ac.build();
// mat = ac.to_mat();
for(int i = 0; i < ac.L; i++)
dp[0][i] = INF;
dp[0][0] = 0;
int cur = 0;
scanf("%s",str);
for(int i = 0; i < (int)strlen(str); i++)
{
cur ^= 1;
for(int i = 0; i < ac.L; i++)
dp[cur][i] = INF;
for(int j = 0; j < ac.L; j++)
{
for(int k = 0; k < 4; k++)
{
if(dp[cur^1][j] != INF && !ac.ed[ac.nex[j][k]])
dp[cur][ac.nex[j][k]] = min(dp[cur][ac.nex[j][k]] , dp[cur^1][j] + (k == ac.cal(str[i]) ? 0:1));
}
}
}
int ans = INF;
for(int i = 0; i < ac.L; i++)
ans = min(ans,dp[cur][i]);
printf("Case %d: ",cas++);
if(ans == INF)
cout << -1 <<"\n";
else
cout << ans <<"\n";
}
return 0;
}
原文:http://www.cnblogs.com/Przz/p/5449309.html