您的位置:首页 > 大数据 > 人工智能

HDU 2457 DNA repair (AC自动机+DP)

2016-06-02 08:06 465 查看
题意:给N个串,一个大串,要求在最小的改变代价下,得到一个不含上述n个串的大串。

思路:dp,f[i][j]代表大串中第i位,AC自动机上第j位的最小代价。

#include<algorithm>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<iostream>
#include<queue>
std::queue<int>Q;
int ch[10005][5],end[10005],f[1005][1005],sz,root,fail[100005],n,Tcase;
char s[10005];
int newnode(){
for (int i=0;i<=3;i++)
ch[sz][i]=-1;
end[sz]=0;
sz++;
return sz-1;
}
void clear(){
sz=0;root=newnode();
}
int num(char c){
if (c=='A') return 0;
else
if (c=='T') return 1;
else
if (c=='G') return 2;
else
if (c=='C') return 3;
return 0;
}
void insert(){
scanf("%s",s);
int len=strlen(s);
int now=root;
for (int i=0;i<len;i++){
if (ch[now][num(s[i])]==-1) ch[now][num(s[i])]=newnode();
now=ch[now][num(s[i])];
}
end[now]=1;
}
void build(){
int now=root;
std::queue<int>Q;
fail[root]=root;
for (int i=0;i<=3;i++)
if (ch[root][i]==-1) ch[root][i]=root;
else fail[ch[root][i]]=root,Q.push(ch[root][i]);
while (!Q.empty()){
int now=Q.front();Q.pop();
if (end[fail[now]]==1) end[now]|=1;
for (int i=0;i<=3;i++){
if (ch[now][i]==-1) ch[now][i]=ch[fail[now]][i];
else fail[ch[now][i]]=ch[fail[now]][i],Q.push(ch[now][i]);
}
}
}
void dp(){
scanf("%s",s);
int len=strlen(s);
for (int i=0;i<=len;i++)
for (int j=0;j<=sz;j++)
f[i][j]=99999999;
f[0][root]=0;
for (int i=0;i<len;i++)
for (int j=0;j<sz;j++)
if (f[i][j]<99999999){
for (int k=0;k<=3;k++){
int now=ch[j][k];
if (end[now]) continue;
int tmp;
if (k==num(s[i])) tmp=f[i][j];
else tmp=f[i][j]+1;
f[i+1][now]=std::min(f[i+1][now],tmp);
}
}
int ans=99999999;
for (int i=0;i<sz;i++)
ans=std::min(ans,f[len][i]);
if (ans==99999999) ans=-1;
printf("%d\n",ans);
}
int main(){
while (scanf("%d",&n)!=EOF){
if (n==0) return 0;
Tcase++;
printf("Case %d: ",Tcase);
clear();
for (int i=1;i<=n;i++)
insert();
build();
dp();
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: