题意:给n个病毒DNA序列,再给一个DNA序列,问该序列至少修改多少个碱基能不含任何病毒DNA。病毒DNA序列一共不超过1000,询问的DNA长度不超过1000。

题解:DP:d[l][p]表示询问到第l位、当前在AC自动机上的位置为p时的最少修改数,用d[l][p]推d[l+1][x]。本来打的是递归,结果递归死循环了。。于是改成递推了。

不想清楚的话递归真的好容易死掉TAT

 //poj3691
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<queue>
using namespace std; const int N=,INF=(int)1e9;
int n,num,sl,ans,d[N][N];
char s[N];
struct node{
int fail,fa,bk,son[];
}a[N];
queue<int> q; int minn(int x,int y){return x<y ? x:y;} int idx(char c)
{
if(c=='A') return ;
if(c=='T') return ;
if(c=='C') return ;
if(c=='G') return ;
} void clear(int x)
{
a[x].bk=a[x].fail=a[x].fa=;
memset(a[x].son,,sizeof(a[x].son));
} void read_trie()
{
scanf("%s",s);
int x=,l=strlen(s);
for(int i=;i<l;i++)
{
int ind=idx(s[i]);
if(!a[x].son[ind])
{
clear(++num);
a[x].son[ind]=num;
a[num].fa=x;
}
x=a[x].son[ind];
}
a[x].bk=;
} void buildAC()
{
while(!q.empty()) q.pop();
for(int i=;i<=;i++)
if(a[].son[i]) q.push(a[].son[i]);
while(!q.empty())
{
int x=q.front();q.pop();
int fail=a[x].fail;
for(int i=;i<=;i++)
{
if(a[x].son[i])
{
int y=a[x].son[i],z=a[fail].son[i];
a[y].fail=z;
a[y].bk|=a[z].bk;
q.push(y);
}
else a[x].son[i]=a[fail].son[i];
}
}
} int main()
{
freopen("a.in","r",stdin);
freopen("a.out","w",stdout);
int T=;
while()
{
scanf("%d",&n);
if(!n) return ;
num=;
clear();
for(int i=;i<=n;i++) read_trie();
buildAC();
scanf("%s",s+);
sl=strlen(s+);
ans=INF;
memset(d,,sizeof(d));
d[][]=;
for(int i=;i<sl;i++)
{
for(int j=;j<=num;j++)//在AC自动机上的位置
{
if(d[i][j]<INF)
{
int ind=idx(s[i+]);
int x=a[j].son[ind];
for(int k=;k<=;k++)
{
int y=a[j].son[k];
if(a[y].bk || x==y) continue;
d[i+][y]=minn(d[i+][y],d[i][j]+);
}
if(a[x].bk==)
d[i+][x]=minn(d[i+][x],d[i][j]);
}
}
}
for(int i=;i<=num;i++) ans=minn(ans,d[sl][i]);
if(ans<INF) printf("Case %d: %d\n",++T,ans);
else printf("Case %d: -1\n",++T);
}
return ;
}

【poj3691-DNA repair】AC自动机+DP的更多相关文章

  1. POJ3691 DNA repair(AC自动机 DP)

    给定N个长度不超过20的模式串,再给定一个长度为M的目标串S,求在目标串S上最少改变多少字符,可以使得它不包含任何的模式串 建立Trie图,求得每个节点是否是不可被包含的串,然后进行DP dp[i][ ...

  2. HDU2457 DNA repair —— AC自动机 + DP

    题目链接:https://vjudge.net/problem/HDU-2457 DNA repair Time Limit: 5000/2000 MS (Java/Others)    Memory ...

  3. HDU 2457/POJ 3691 DNA repair AC自动机+DP

    DNA repair Problem Description   Biologists finally invent techniques of repairing DNA that contains ...

  4. [hdu2457]DNA repair(AC自动机+dp)

    题意:给出一些不合法的模式DNA串,给出一个原串,问最少需要修改多少个字符,使得原串中不包含非法串. 解题关键:多模式串匹配->AC自动机,求最优值->dp,注意在AC自动机上dp的套路. ...

  5. POJ 3691 DNA repair(AC自动机+DP)

    题目链接 能AC还是很开心的...此题没有POJ2778那么难,那个题还需要矩阵乘法,两个题有点相似的. 做题之前,把2778代码重新看了一下,回忆一下当时做题的思路,回忆AC自动机是干嘛的... 状 ...

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

    题意:给N个串,一个大串,要求在最小的改变代价下,得到一个不含上述n个串的大串. 思路:dp,f[i][j]代表大串中第i位,AC自动机上第j位的最小代价. #include<algorithm ...

  7. hdu_2457_DNA repair(AC自动机+DP)

    题目连接:hdu_2457_DNA repair 题意: 给你N个字符串,最后再给你一个要匹配的串,问你最少修改多少次,使得这个串不出现之前给的N的字符串 题解: 刚学AC自动机,切这题还真不知道怎么 ...

  8. poj 2778 DNA Sequence AC自动机DP 矩阵优化

    DNA Sequence Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 11860   Accepted: 4527 Des ...

  9. POJ 2778 DNA Sequence (AC自动机+DP+矩阵)

    题意:给定一些串,然后让你构造出一个长度为 m 的串,并且不包含以上串,问你有多少个. 析:很明显,如果 m 小的话 ,直接可以用DP来解决,但是 m 太大了,我们可以认为是在AC自动机图中,根据离散 ...

  10. HDU 2425 DNA repair (AC自动机+DP)

    DNA repair Time Limit: 5000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

随机推荐

  1. netfilter

    http://jingyan.baidu.com/article/642c9d3415d2c9644a46f7c6.html http://blog.csdn.net/zhangskd/article ...

  2. libevent简介 构成

    libevent简介 libevent是一个事件驱动的网络库,支持跨平台,如Linux, *BSD, MacOS X, Solaris, Windows.支持I/O多路复用,epoll.poll./d ...

  3. iOS学习之Object-C语言集合遍历和数组排序

    一.集合遍历      1.集合:OC中提供的容器类,数组,字典,集合.      2.遍历:对集合中元素依次取出的过程叫做遍历. 二.for循环遍历      1.通过for循环的循环变量用作数组元 ...

  4. A taste of urllib3

    import urllib3 import certifi http = urllib3.PoolManager( cert_reqs='CERT_REQUIRED', # Force certifi ...

  5. ABAP自定义类的构造方法

    REPORT ytest_011. *----------------------------------------------------------------------* * CLASS z ...

  6. Kinect帮助文档翻译之一 入门

    最近在玩Kinect,使用的是Unity,发现网上好像没有什么教程.自己就只有抱着英文版帮助文档啃,真是苦逼 本人英语也不好,大家将就着看吧 Kinect入门帮助 如何运行示例 1       下载并 ...

  7. C# 把引用的dll嵌入到exe文件中

    当发布的程序有引用其它dll, 又只想发布一个exe时就需要把dll打包到exe 当然有多种方法可以打包, 比如微软的ILMerge,混淆器附带的打包... 用代码打包的实现方式也有很好,本文只是其中 ...

  8. 20145120 《Java程序设计》第9周学习总结

    20145120 <Java程序设计>第9周学习总结 教材学习内容总结 JDBC希望程序能操作所有数据库 操作JDBC驱动有4种类型: JDBC-ODBC Bridge Driver Na ...

  9. C#制作高仿360安全卫士窗体(四)- 水晶按钮

    项目越来越紧,我也乐此不疲.自从上次C#制作高仿360安全卫士窗体(三)出来之后,就开始有一些人在说为什么还在坚持写这么落后的东西.我想说的是,我是从事企业信息化工作的,所有程序都只对内部使用.所以只 ...

  10. 浅谈自我对git的初步认识

    本学期我们新增了一门课程,那就是软件工程,不知道为什么,感觉有种莫名的高大上.哈哈!难道是这个名称太抽象了吗?这个问题我感觉到后来肯定就明白了. 第一次博客,感觉好紧张哦,嘿嘿!老师让我们谈谈对git ...