题意:给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. java 静态变量生命周期(类生命周期)

    Static: 加载:java虚拟机在加载类的过程中为静态变量分配内存. 类变量:static变量在内存中只有一个,存放在方法区,属于类变量,被所有实例所共享 销毁:类被卸载时,静态变量被销毁,并释放 ...

  2. VC++编程之对话框贴图

    基于对话框的程序写好后,为对话框贴上个图片让界面更加美观(我承认做界面,MFC显得力不从心,不如QT). 其实很简单,我们以位图为例,选好我们需要的位图资源(bmp),假若自己的图片不是位图资源,可以 ...

  3. Linux C 文件与目录3 文件读写

    文件读写 文件读写是指从文件中读出信息或将信息写入到文件中.Linux文件读取可使用read函数来实现的,文件写入可使用write函数来实现.在进行文件写入的操作时,只是在文件的缓冲区中操作,可能没有 ...

  4. 模仿cocos2dx 风格用工厂方法,实现class A,不使用宏,

    class A { static A *create(); bool init(); }; A* A::create() { A *pRet=new A; if(pRet && pRe ...

  5. 面向对象设计SOLID五大原则

    转载自:码农社区,http://w3croom.com/read.php?tid-4522.html 今天我给大家带来的是面向对象设计SOLID五大原则的经典解说.       我们知道,面向对象对于 ...

  6. Log4j的常见用法

    对于log4j,一般常用的只要保存如下的内容为属性文件即可: #log4j.rootLogger=DEBUG,A1,R log4j.rootLogger=INFO,A1,R log4j.appende ...

  7. php file_put_contents() 写入回车

    PHP file_put_contents() 函数是一次性向文件写入字符串或追加字符串内容的最合适选择. file_put_contents() file_put_contents() 函数用于把字 ...

  8. 3、颜色的字符串、十进制、十六进制相互转换(color convert between dec、hex and string )

    int color_int=***; 1.(十进制整数)转换成(十六进制的字符串) String color_hex = String.format("#%06X", (0xFFF ...

  9. EF 更新条目时出错。有关详细信息,请参见内部异常。

    现象:使用EF新增记录时,一直报上述异常,网上说是值为空.主键外键未设等原因导致,但是改正这些情况下问题依然 解决过程:异常中有一句(请参见内部异常),一直都没有当回事,后来实在没办法就静下心来看了看 ...

  10. JS 学习笔记--2--变量的声明

      1.ECMAScript 中规定所有的关键字.保留字.函数名.函数名.操作符等都是区分大小写的. 2.标识符:指变量.函数.属性的名字:标识符组成:以字母.下划线.$ 开头,其他字母可以含有数字, ...