[hdu2457]DNA repair(AC自动机+dp)
2017-09-14 02:05
309 查看
题意:给出一些不合法的模式DNA串,给出一个原串,问最少需要修改多少个字符,使得原串中不包含非法串。
解题关键:多模式串匹配->AC自动机,求最优值->dp,注意在AC自动机上dp的套路。
AC自动机上的每个节点其实就是一种状态,进行模式匹配其实就是进行边的匹配
令$dp[i][j]$表示字符串长度为$i$时到达AC自动机上某个状态所需要修改的最小值。
转移方程:$dp[i + 1][Next[j][k]] = \min (dp[i][j] + (k! = str[i]),dp[i + 1][Next[j][k]])$
#include<cstdio> #include<cstring> #include<algorithm> #include<cstdlib> #include<cstring> #include<iostream> #include<queue> #define inf 0x3f3f3f3f using namespace std; typedef long long ll; const int N=4; const int MAXN=1010; ll m,n; int dp[1002][MAXN]; struct Trie{ int Next[MAXN] ,Fail[MAXN],root,tot; bool End[MAXN]; int newnode(){ for(int i=0;i<N;i++) Next[tot][i]=-1; End[tot++]=false; return tot-1; } void init(){ tot=0; root=newnode(); } void insert(char buf[]){ int len=strlen(buf),now=root,k; for(int i=0;i<len;i++){ if(buf[i]=='A') k=0; else if(buf[i]=='G') k=1; else if(buf[i]=='C') k=2; else k=3; if(Next[now][k]==-1) Next[now][k]=newnode(); now=Next[now][k]; } End[now]=true; } void build(){ queue<int>que; Fail[root]=root; for(int i=0;i<N;i++){ if(Next[root][i]==-1) Next[root][i]=root; else{ Fail[Next[root][i]]=root; que.push(Next[root][i]); } } while(!que.empty()){ int now=que.front(); que.pop(); if(End[Fail[now]]) End[now]=true; for(int i=0;i<N;i++){ if(Next[now][i]==-1) Next[now][i]=Next[Fail[now]][i];//Next指针都已经建立好 else{ Fail[Next[now][i]]=Next[Fail[now]][i]; que.push(Next[now][i]); } } } } int solve(char buf[]){ int len=strlen(buf); for(int i=0;i<=len;i++) for(int j=0;j<=tot;j++) dp[i][j]=inf; dp[0][0]=0; for(int i=0;i<len;i++){//最主要的事情就是分清边和点 int tmp; if(buf[i]=='A') tmp=0; else if(buf[i]=='G') tmp=1; else if(buf[i]=='C') tmp=2; else tmp=3; for(int j=0;j<tot;j++){ if(dp[i][j]==inf||End[j]) continue; for(int k=0;k<4;k++){ int u=Next[j][k]; if(End[u]) continue; dp[i+1][u]=min(dp[i][j]+(tmp!=k),dp[i+1][u]); } } } int ans=inf; for(int i=0;i<tot;i++) ans=min(ans,dp[len][i]); return ans==inf?-1:ans; } }; Trie ac; char buf[2200]; int main(){ int ca=0; while(scanf("%d",&n)&&n){ ca++; ac.init(); for(int i=0;i<n;i++) scanf("%s",buf),ac.insert(buf); ac.build(); scanf("%s",buf); int ans=ac.solve(buf); printf("Case %d: %d\n",ca,ans); } }
相关文章推荐
- hdu2457---DNA repair(AC自动机+dp)
- hdu2457 DNA repair(AC自动机+dp)
- hdu2457 DNA repair(AC自动机+dp)
- HDU2457 DNA repair(AC自动机+DP)
- hdu 2457 DNA repair(ac自动机+dp)
- POJ 3691 DNA repair(AC自动机+dp)
- 【POJ3691】 DNA repair (AC自动机+DP)
- poj 3691 DNA repair(AC自动机+DP)
- hdu 2457 DNA repair (ac自动机+dp)
- POJ 3691 DNA repair(AC自动机+DP)
- HDU 2457-DNA repair(AC自动机+DP)
- poj 3691 DNA repair(AC自动机+dp)
- POJ 3691 DNA repair(AC自动机+DP)
- POJ 3691 DNA repair (AC自动机+dp)
- HDU 2457 DNA repair(AC自动机+DP)
- HDU 2457 DNA repair(AC自动机+DP)
- HDU - 2457 DNA repair(AC自动机+DP)
- hdu_2457_DNA repair(AC自动机+DP)
- hdu_2457_DNA repair(AC自动机+DP)
- Poj 3691 & Hdu 2457 DNA repair (AC自动机+DP)