poj3691 DNA repair[DP+AC自动机]
$给定 n 个模式串,和一个长度为 m 的原串 s,求至少修改原串中的几个字符可以使得原串中不包含任一个模式串。模式串总长度 ≤ 1000,m ≤ 1000。$
先建出模式串的AC自动机,然后考虑怎么求最优解。考虑AC自动机上DP,设$f_{i,j}$走了$i$步之后在$j$节点时候的最少修改次数。
标记处所有不能走到的点(即走到就匹配了的点,即后缀为某一模式串的所有点),走点的时候应当回避这些点,转移的时候向合法的状态转移,分两种。
一种沿着原串$s_i$走,$f_{i+1,to_j}\leftarrow f_{i,j}$,另一种是走其他路,$f_{i+1,to_j'}\leftarrow f_{i,j}+1$。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#define dbg(x) cerr << #x << " = " << x <<endl
using namespace std;
typedef long long ll;
typedef double db;
typedef pair<int,int> pii;
template<typename T>inline T _min(T A,T B){return A<B?A:B;}
template<typename T>inline T _max(T A,T B){return A>B?A:B;}
template<typename T>inline char MIN(T&A,T B){return A>B?(A=B,):;}
template<typename T>inline char MAX(T&A,T B){return A<B?(A=B,):;}
template<typename T>inline void _swap(T&A,T&B){A^=B^=A^=B;}
template<typename T>inline T read(T&x){
x=;int f=;char c;while(!isdigit(c=getchar()))if(c=='-')f=;
while(isdigit(c))x=x*+(c&),c=getchar();return f?x=-x:x;
}
const int N=+,INF=0x3f3f3f3f;
int ha[],tr[N][],ban[N],nxt[N],legal[N],cnt,tot;
char s[N];
int n;
inline void Insert(){
int len=strlen(s+),x=;
for(register int i=,c=ha[s[]];i<=len;++i,c=ha[s[i]]){
if(!tr[x][c])tr[x][c]=++tot;
x=tr[x][c];
}
ban[x]=;
}
queue<int> q;
inline void Build(){
legal[cnt=]=;
memset(nxt,,sizeof nxt);
for(register int i=;i<;++i)if(tr[][i])nxt[tr[][i]]=,q.push(tr[][i]);
while(!q.empty()){
int x=q.front();q.pop();
if(ban[nxt[x]])ban[x]=;
if(!ban[x])legal[++cnt]=x;
for(register int i=;i<;++i)
if(tr[x][i])nxt[tr[x][i]]=tr[nxt[x]][i],q.push(tr[x][i]);
else tr[x][i]=tr[nxt[x]][i];
}
}
#define j legal[_]
int f[N][N],ans,T;
inline void dp(){
memset(f,0x3f,sizeof f);
f[][]=;ans=INF;
int len=strlen(s+);
for(register int i=;i<len;++i)
for(register int _=;_<=cnt;++_)if(f[i][j]<INF){
int c=ha[s[i+]];//dbg(i),dbg(j),dbg(f[i][j]);
for(register int k=;k<;++k)
if(!ban[tr[j][k]]&&(c^k))
MIN(f[i+][tr[j][k]],f[i][j]+);
if(!ban[tr[j][c]])MIN(f[i+][tr[j][c]],f[i][j]);
}
for(register int _=;_<=cnt;++_)MIN(ans,f[len][j]);
}
#undef j
int main(){//freopen("test.in","r",stdin);//freopen("test.ans","w",stdout);
ha['A']=,ha['C']=,ha['G']=,ha['T']=;
while(read(n)){
memset(ban,,sizeof ban);memset(tr,,sizeof tr),tot=;
for(register int i=;i<=n;++i)scanf("%s",s+),Insert();
Build();scanf("%s",s+);dp();
printf("Case %d: %d\n",++T,ans<INF?ans:-);
}
return ;
}
总结:AC自动机上DP多为$f_{i,j}$型状态设计,需要考虑每一步各种转移情况。过于浅薄
poj3691 DNA repair[DP+AC自动机]的更多相关文章
- HDU 2457 DNA repair(AC自动机+DP)题解
题意:给你几个模式串,问你主串最少改几个字符能够使主串不包含模式串 思路:从昨天中午开始研究,研究到现在终于看懂了.既然是多模匹配,我们是要用到AC自动机的.我们把主串放到AC自动机上跑,并保证不出现 ...
- 【POJ3691】 DNA repair (AC自动机+DP)
DNA repair Time Limit: 2000MS Memory Limit: 65536KB 64bit IO Format: %I64d & %I64u Description B ...
- HDU 2425 DNA repair (AC自动机+DP)
DNA repair Time Limit: 5000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total ...
- HDU2457 DNA repair(AC自动机+DP)
题目一串DNA最少需要修改几个基因使其不包含一些致病DNA片段. 这道题应该是AC自动机+DP的入门题了,有POJ2778基础不难写出来. dp[i][j]表示原DNA前i位(在AC自动机上转移i步) ...
- 【POJ3691】DNA repair(AC自动机,DP)
题意: 生物课上我们学到,DNA序列中只有A, C, T和G四种片段. 经科学发现,DNA序列中,包含某些片段会产生不好的基因,如片段"ATC"是不好片段,则"AGATC ...
- 咕咕(数位dp+AC自动机)
咕咕(数位dp+AC自动机) 若一个字符串的字符集合是0~m-1,那么称它为m进制字符串.给出n个m进制字符串\(s_i\),每个字符串的权值为\(v_i\).对于另一个m进制字符串\(S\),设\( ...
- 洛谷$P4045\ [JSOI2009]$密码 $dp$+$AC$自动机
正解:$dp$+$AC$自动机+搜索 解题报告: 传送门$QwQ$ 首先显然先建个$AC$自动机,然后考虑设$f_{i,j,k}$表示长度为$i$,现在在$AC$自动机的第$j$个位置,已经表示出来的 ...
- POJ 3691 DNA repair (DP+AC自动机)
DNA repair Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 4815 Accepted: 2237 Descri ...
- 【AC自动机】【动态规划】poj3691 DNA repair
http://blog.csdn.net/kk303/article/details/6929641 http://blog.csdn.net/human_ck/article/details/657 ...
随机推荐
- java_guide_9-30_并发相关
3.1 CopyOnWriteArrayList 简介 public class CopyOnWriteArrayList<E> extends Object implements Lis ...
- createjs小游戏开发总结
createjs缩放,html组件input的缩放,transform位置,缩放,字体的大小. 移动端横屏和竖屏幕旋转屏幕自适应,input弹出软键盘的原理和位置偏移,focus,blur弹出软键盘. ...
- [转帖]Docker学习之Dockerfile命令详解
Docker学习之Dockerfile命令详解 https://it.baiked.com/system/docker/2436.html 图挺好的 前言 之前,制作镜像的伪姿势搭建已经见过了,今天介 ...
- Educational Codeforces Round 68 (Rated for Div. 2)补题
A. Remove a Progression 签到题,易知删去的为奇数,剩下的是正偶数数列. #include<iostream> using namespace std; int T; ...
- Codeforces 1236B. Alice and the List of Presents
传送门 显然每种礼物是互相独立的,一个礼物的分配不会影响另一个礼物 对于某个礼物 $x$ , 对于每个盒子来说,要么选要么不选,那么可以看成长度为 $m$ 的二进制序列 这个序列第 $i$ 位的数就代 ...
- 数值优化(Numerical Optimization)学习系列-无梯度优化(Derivative-Free Optimization)
数值优化(Numerical Optimization)学习系列-无梯度优化(Derivative-Free Optimization) 2015年12月27日 18:51:19 下一步 阅读数 43 ...
- hype-v上centos7部署高可用kubernetes集群实践
概述 在上一篇中已经实践了 非高可用的bubernetes集群的实践 普通的k8s集群当work node 故障时是高可用的,但是master node故障时将会发生灾难,因为k8s api serv ...
- merge into使用方法
此外,You cannot update a column that is referenced in the ON condition clause.,update的字段不可以是on里面的条件字段, ...
- 【原创】大叔经验分享(56)hue导出行数限制
/opt/cloudera/parcels/CDH/lib/hue/apps/beeswax/src/beeswax/conf.py # Deprecated DOWNLOAD_CELL_LIMIT ...
- pthread 笔记
1.创建线程 res = pthread_create(&a_thread, NULL, thread_function1, NULL); if (res != 0) { perror(&qu ...