hdu_2457_DNA repair(AC自动机+DP)
来源:互联网 发布:淘宝达人精品帖子 编辑:程序博客网 时间:2024/05/19 17:50
题目连接:hdu_2457_DNA repair
题意:
给你N个字符串,最后再给你一个要匹配的串,问你最少修改多少次,使得这个串不出现之前给的N的字符串
题解:
刚学AC自动机,切这题还真不知道怎么来DP,然后看了一下题解,需要在失败指针那里做文章,这里我们要将trie的每一个节点当作一个状态,然后设dp[i][j]表示考虑到第i个字符,j这个trie节点时的最小修改次数,为什么要这样考虑,因为AC自动机在匹配失败的时候会转向其他的节点,所以这里我们要考虑每一个节点的状态,然后当前节点的子节点如果不存在也要处理一下,就指向这个节点的fail指针,这样我们在后面dp的时候才能保证匹配失败的时候回到fail节点
#include<cstdio>#include<cstring>#define F(i,a,b) for(int i=a;i<=b;i++)inline void up(int &x,int y){if(x>y)x=y;}const int AC_N=1011,inf=1e8;struct AC_automation{ int tr[AC_N][4],cnt[AC_N],Q[AC_N],fail[AC_N],tot; int gt(char x){ if(x=='A')return 0; if(x=='G')return 1; if(x=='C')return 2; if(x=='T')return 3; } void nw(){cnt[++tot]=0;memset(tr[tot],-1,sizeof(tr[tot]));} void init(){tot=-1,fail[0]=-1,nw();} void insert(char *s,int x=0){ for(int len=strlen(s),i=0,w;i<len;x=tr[x][w],i++) if(tr[x][w=gt(s[i])]==-1)nw(),tr[x][w]=tot; cnt[x]=1;//串尾标记 } void build(int head=1,int tail=0){ for(Q[++tail]=0;head<=tail;){ for(int i=0,x=Q[head++],p=-1;i<=3;i++)if(~tr[x][i]){ if(x==0)fail[tr[0][i]]=0; else{ for(p=fail[x],fail[tr[x][i]]=0;~p;p=fail[p]) if(~tr[p][i]){fail[tr[x][i]]=tr[p][i];break;} }//如果他失败指针指向的节点的子节点为危险DNA那么这点的子节点也不能取 if(cnt[fail[tr[x][i]]])cnt[tr[x][i]]=1; Q[++tail]=tr[x][i]; }else if(x==0)tr[0][i]=0;//不存在的节点指向失败指针的位置 else tr[x][i]=tr[fail[x]][i]; } } int dp[1010][1010]; int ask(char *s){ int len=strlen(s),ans=inf; F(i,0,len)F(j,0,tot)dp[i][j]=inf; dp[0][0]=0; F(i,1,len)F(j,0,tot){ if(cnt[j]||dp[i-1][j]==inf)continue; F(k,0,3){ int nxt=tr[j][k]; if(cnt[nxt])continue; up(dp[i][nxt],dp[i-1][j]+(gt(s[i-1])!=k)); } } F(i,0,tot)up(ans,dp[len][i]); return ans==inf?-1:ans; }}AC;char buf[1010];int main(){ int n,ic=1; while(~scanf("%d",&n),n){ AC.init(); F(i,1,n)scanf("%s",buf),AC.insert(buf); AC.build(); scanf("%s",buf); printf("Case %d: %d\n",ic++,AC.ask(buf)); } return 0;}
0 0
- hdu_2457_DNA repair(AC自动机+DP)
- poj3691DNA repair AC自动机+dp
- [AC自动机+dp]PKU 3691--DNA repair
- POJ--3691[DNA repair] AC自动机+DP
- POJ 3691:DNA repair(AC自动机+DP)
- 【AC自动机+DP】 hdu3691 DNA repair
- POJ 3691 DNA repair【AC自动机+DP】
- hdu2457 & poj3691 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:DNA repair【AC自动机+DP】
- 【POJ3691】DNA repair AC自动机+DP
- Hdu 2457 DNA repair (ac自动机+dp)
- [AC自动机+dp] hdu 2457 DNA repair
- hdu 2457 DNA repair(AC自动机+DP)
- POJ 3691 DNA repair AC自动机DP
- Java多线程简介和两种实现方法
- Django输出非HTML内容
- hive的order by语句分析
- Linux内存管理基础
- html meta
- hdu_2457_DNA repair(AC自动机+DP)
- java的面向对象
- 【JZOJ 4629】修路
- 【NOIP2016提高A组模拟7.15】立方体
- mysql replace into,insert into ... on duplicate key
- 左右侧滑
- JS保留正数小数2位
- java模拟登录qq网站,实现一键签到等等功能
- 最小最大和