【xsy1012】KSHKM的基因工程 AC自动机DP
题目大意:给你$n$个串$p_i$,最后再给一个串$s$(字符集均为A,C,G,T四个字符中的一个)。问你串$s$最少要更改多少个字符(更改后的字符也只能是ACGT),才能满足s中不包含$p_i$$(1≤i≤n)$
数据范围:$n≤50$,$|p|≤20$,$|s|≤100$。不超过100组数据。
此题显然是一个AC自动机DP题。
我们首先建出字符串集合$p$的AC自动机。
不难发现,这个自动机中有很多个节点是不能被遍历到的(如果遍历到了串就会包含某些不合法串)
设$f[i][j]$表示我们已经扫描完了串$s$中前i个字符,且当前遍历到了自动机第$j$号点时,最少需要改变的字符数量。
然后枚举我们要在第$i+1$位填什么字符,是否会增加贡献。
也就是说,我们可以用$f[i][j]$的值来更新$f[i+1][ch[j][char]]$,其中$ch[j][char]$表示在$j$号节点往下填字符$char$会跑到哪个点(详见代码)
然后就没有了
复杂度:$O(nps)$。
#include<bits/stdc++.h>
#define M 1005
#define INF 16843009
#define fmin(x,y) ((x)>(y)?(x)=(y):0)
using namespace std; int id[]={}; struct trie{int a[],fail,no;}a[M];int use=;
void add(char c[]){
int len=strlen(c),now=;
for(int i=;i<len;i++){
int k=id[c[i]];
if(a[now].a[k]) now=a[now].a[k];
else a[now].a[k]=++use,now=use;
}
a[now].no=;
}
void makefail(){
queue<int> q; q.push();
while(!q.empty()){
int u=q.front(); q.pop();
for(int i=;i<;i++) if(a[u].a[i]){
a[a[u].a[i]].no|=a[u].no;
q.push(a[u].a[i]);
if(u){
int f=a[u].fail;
while(f&&a[f].a[i]==) f=a[f].fail;
a[a[u].a[i]].fail=a[f].a[i];
a[a[u].a[i]].no|=a[a[f].a[i]].no;
}
}else{
a[u].a[i]=a[a[u].fail].a[i];
}
}
} int s[M]={},f[M][M]={};char str[M]={}; int main(){
id['A']=; id['C']=; id['G']=; id['T']=;
for(int cas=;;cas++){
memset(s,,sizeof(s)); memset(a,,sizeof(a)); use=;
int n; scanf("%d",&n);
if(n==) return ;
for(int i=;i<=n;i++){
scanf("%s",str);
add(str);
}
makefail();
scanf("%s",str+); int len=strlen(str+);
for(int i=;i<=len;i++) s[i]=id[str[i]];
memset(f,,sizeof(f)); f[][]=;
for(int i=;i<len;i++){
for(int j=;j<=use;j++)
if(f[i][j]!=INF){
for(int k=;k<;k++){
int pls=(k!=s[i+]);
if(a[a[j].a[k]].no) continue;
fmin(f[i+][a[j].a[k]],f[i][j]+pls);
}
}
}
int minn=INF;
for(int j=;j<=use;j++) if(a[j].no==)
fmin(minn,f[len][j]);
printf("Case %d: ",cas);
if(minn==INF) cout<<-<<endl;
else cout<<minn<<endl;
}
}
【xsy1012】KSHKM的基因工程 AC自动机DP的更多相关文章
- POJ1625 Censored!(AC自动机+DP)
题目问长度m不包含一些不文明单词的字符串有多少个. 依然是水水的AC自动机+DP..做完后发现居然和POJ2778是一道题,回过头来看都水水的... dp[i][j]表示长度i(在自动机转移i步)且后 ...
- HDU2296 Ring(AC自动机+DP)
题目是给几个带有价值的单词.而一个字符串的价值是 各单词在它里面出现次数*单词价值 的和,问长度不超过n的最大价值的字符串是什么? 依然是入门的AC自动机+DP题..不一样的是这题要输出具体方案,加个 ...
- HDU2457 DNA repair(AC自动机+DP)
题目一串DNA最少需要修改几个基因使其不包含一些致病DNA片段. 这道题应该是AC自动机+DP的入门题了,有POJ2778基础不难写出来. dp[i][j]表示原DNA前i位(在AC自动机上转移i步) ...
- hdu 4117 GRE Words AC自动机DP
题目:给出n个串,问最多能够选出多少个串,使得前面串是后面串的子串(按照输入顺序) 分析: 其实这题是这题SPOJ 7758. Growing Strings AC自动机DP的进阶版本,主题思想差不多 ...
- hdu 2457(ac自动机+dp)
题意:容易理解... 分析:这是一道比较简单的ac自动机+dp的题了,直接上代码. 代码实现: #include<stdio.h> #include<string.h> #in ...
- HDU 2425 DNA repair (AC自动机+DP)
DNA repair Time Limit: 5000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total ...
- HDU2296——Ring(AC自动机+DP)
题意:输入N代表字符串长度,输入M代表喜欢的词语的个数,接下来是M个词语,然后是M个词语每个的价值.求字符串的最大价值.每个单词的价值就是单价*出现次数.单词可以重叠.如果不止一个答案,选择字典序最小 ...
- tyvj P1519 博彩游戏(AC自动机+DP滚动数组)
P1519 博彩游戏 背景 Bob最近迷上了一个博彩游戏…… 描述 这个游戏的规则是这样的:每花一块钱可以得到一个随机数R,花上N块钱就可以得到一个随机序列:有M个序列,如果某个序列是产生的随机序列的 ...
- bzoj 1030 [JSOI2007]文本生成器(AC自动机+DP)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1030 [题意] 给n个小串,随机构造一个长为m的大串,一个串合法当且仅当包含一个或多个 ...
随机推荐
- 2018.10.24 NOIP模拟 小 C 的宿舍(分治)
传送门 分治妙题. 没有这道题的暴力分今天又垫底了啊233 由于用了分治的方法,我们只用考虑左区间对右区间的贡献以及右区间对左区间的贡献. 可以发现如果从中点开始向两边递推最小值并用这个区间最小值来推 ...
- 使用docker 安装 GITLIB
在安装 gitlib 社区版时,配置老不成功,改成使用docker安装 比较顺利,省事. 1外部卷配置 docker 需要配置一些卷在外部,创建一下git的目录 我们创建一个在home下 创建一个gi ...
- s4-7 生成树协议
Spanning Tree :为了可靠,采用冗余结构:但是透明网桥 会产生无休止循环的问题 冗余交换拓扑可能带来的问题 广播风暴 多帧传送 MAC地址库不稳定 生成树协议 STP:sp ...
- go语言判断末尾不同的长字符串的方法
判断两种末尾不同的长字符串,在使用正则表达式的基础上,进一步利用好字符串的方法,最后成功对问题进行解决. package utils import ( "io/ioutil" &q ...
- php 大文件上传的实现
最近公司做工程项目,实现大文件上传 网上找了很久,发现网上很多代码大都存在很多问题,不过还是让我找到了一个符合要求的项目. 工程: 对项目的文件上传功能做出分析,找出文件上传的原理,对文件的传输模式深 ...
- Python实现文件备份
Python实现文件拷贝 2017年8月27日 1.实现目的 统一时间对服务器某文件夹内文件进行备份保存,如若备份成功则不提示任何错误,否则将以邮件的形式告知管理员,备份出错. 2.程序流程图 主要流 ...
- redis.conf之save配置项解读
配置示例: save 900 1 save 300 10 save 60 3600 配置解读: 1) “save 900 1”表示如果900秒内至少1个key发生变化(新增.修改和删除),则重写rdb ...
- noip第16课作业
1. 猴子吃桃 [问题描述] 猴子第一天摘了若干个桃子,当即吃了一半,还不解馋,又多吃了一个:第二天,吃剩下的桃子的一半,还不过瘾,又多吃了一个:以后每天都吃前一天剩下的一半多一个,到第10天想再吃时 ...
- vc6中向vs2010迁移的几个问题
vc6版本支持的库编译:CJ60lib 1. 用vs2010打开CJ60库的源码的dsw,强制打开 (1)设置项目属性的语言 因为,如果代码字符的编码集不一样,则会出现函数冲定义,参数冲突等问题,这可 ...
- JVM的參數
博客:https://www.cnblogs.com/redcreen/archive/2011/05/04/2037057.html#CMSInitiatingOccupancyFraction_v ...