直接从root遍历扩展DP,当扩展到的字母和字符串字母相同时,不用修改,不同时,要求修改加1

注意不要扩展危险结点。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <climits>
#include <string.h>
#include <queue>
#include <cmath>
#include <map>
#include <vector>
#define LL __int64
using namespace std; const int Maxn=1010;
const int dictsize=4;
const int root=0;
const int inf=(1<<30);
int ids['Z'];
int fail[Maxn],trie[Maxn][dictsize];
bool tag[Maxn];
int head,tail,tot;
int que[Maxn];
char str[Maxn];
int n;
int dp[Maxn][Maxn]; void Insert_trie(){
int p=0,i=0,index;
while(str[i]){
index=ids[str[i]];
if(trie[p][index]==-1) trie[p][index]=++tot;
p=trie[p][index];
i++;
}
tag[p]=true;
} void build_ac(){
head=tail=0;
que[tail++]=root;
while(head!=tail){
int tmp=que[head++];
int p=-1;
for(int i=0;i<dictsize;i++){
if(trie[tmp][i]!=-1){
if(tmp==root) fail[trie[tmp][i]]=root;
else{
p=fail[tmp];
while(p!=-1){
if(trie[p][i]!=-1){
fail[trie[tmp][i]]=trie[p][i];
break;
}
p=fail[p];
}
if(p==-1) fail[trie[tmp][i]]=root;
}
if(tag[fail[trie[tmp][i]]]) tag[trie[tmp][i]]=true;
que[tail++]=trie[tmp][i];
}
else{ //trie[tmp][i]==-1
if(tmp==root) trie[tmp][i]=root;
else{
p=fail[tmp];
while(p!=-1){
if(trie[p][i]!=-1){
trie[tmp][i]=trie[p][i];
break;
}
p=fail[p];
}
if(p==-1) trie[tmp][i]=root;
}
}
}
}
} int main(){
int T=0;
ids['A']=0,ids['C']=1,ids['G']=2,ids['T']=3;
while(scanf("%d",&n)&&n){
head=tail=tot=0;
memset(fail,-1,sizeof(fail));
memset(trie,-1,sizeof(trie));
memset(tag,false,sizeof(tag));
for(int i=0;i<n;i++){
scanf("%s",str);
Insert_trie();
}
scanf("%s",str+1);
build_ac();
int len=strlen(str+1);
memset(dp,-1,sizeof(dp));
dp[0][0]=0; int son;
for(int j=0;j<len;j++){
for(int i=0;i<=tot;i++){
if(dp[i][j]>=0){
for(int k=0;k<dictsize;k++){
if(!tag[trie[i][k]]){
son=trie[i][k];
if(k==ids[str[j+1]]){
if(dp[son][j+1]==-1){
dp[son][j+1]=dp[i][j];
}
else{
dp[son][j+1]=min(dp[i][j],dp[son][j+1]);
}
}
else{
if(dp[son][j+1]==-1){
dp[son][j+1]=dp[i][j]+1;
}
else{
dp[son][j+1]=min(dp[i][j]+1,dp[son][j+1]);
}
}
}
}
}
}
}
int ans=inf;
for(int i=0;i<=tot;i++){
if(dp[i][len]!=-1){
ans=min(ans,dp[i][len]);
}
}
printf("Case %d: %d\n",++T,ans==inf?-1:ans);
}
return 0;
}

  

HDU 2457的更多相关文章

  1. HDU 2457 DNA repair(AC自动机+DP)题解

    题意:给你几个模式串,问你主串最少改几个字符能够使主串不包含模式串 思路:从昨天中午开始研究,研究到现在终于看懂了.既然是多模匹配,我们是要用到AC自动机的.我们把主串放到AC自动机上跑,并保证不出现 ...

  2. POJ 3691 &amp; HDU 2457 DNA repair (AC自己主动机,DP)

    http://poj.org/problem?id=3691 http://acm.hdu.edu.cn/showproblem.php?pid=2457 DNA repair Time Limit: ...

  3. hdu 2457(ac自动机+dp)

    题意:容易理解... 分析:这是一道比较简单的ac自动机+dp的题了,直接上代码. 代码实现: #include<stdio.h> #include<string.h> #in ...

  4. hdu 2457 DNA repair

    AC自动机+DP.按着自动机跑,(其实是生成新的满足题目要求的串,然后找改变最少的.)但是不能跑到是单词的地方,如果跑到单词的话那么说明改变后的串含有病毒了,不满足题意.然后就是应该怎么跑的问题了,现 ...

  5. DNA repair - HDU 2457(自动机+dp)

    题目大意:给你N个DNA的串,也就是至包含'A','T','G','C'四种碱基的,这些给定的串都是带有遗传病的,然后给你一个不会超过1000的串,问你至少几个地方才能让这个串不包含遗传病,如果不论怎 ...

  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)

    题目大意: 改动文本串的上的字符,使之不出现上面出现的串.问最少改动多少个. 思路分析: dp[i][j]表示如今 i 个字符改变成了字典树上的 j 节点. 然后顺着自己主动机一直转移方程. 注意合法 ...

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

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

  9. DNA repair HDU - 2457 AC自动机+DP

    题意: 给你N个模板串,并且给你一个文本串, 现在问你这个文本串最少需要改变几个字符才能使得它不包含任何模板串. (以上字符只由A,T,G,C构成) 题解: 刚开始做这一题的时候表示很懵逼,好像没有学 ...

随机推荐

  1. 使用pycharm进行简单的数据库管理

    功能简介 pycharm自带了一个简单的数据库插件,可以比较方便的进行简单的数据库操作. 例如: 1.创建,修改和删除数据表,字段,索引,主键,外键等. 2.提供table editor来进行数据操作 ...

  2. python 内存泄露的诊断

    对于一个用 python 实现的,长期运行的后台服务进程来说,如果内存持续增长,那么很可能是有了"内存泄露" 一.内存泄露的原因 对于 python 这种支持垃圾回收的语言来说,怎 ...

  3. C Looooops(扩展欧几里得+模线性方程)

    http://poj.org/problem?id=2115 题意:给出A,B,C和k(k表示变量是在k位机下的无符号整数),判断循环次数,不能终止输出"FOREVER". 即转化 ...

  4. NPM 国内镜像使用方法

    npm官方站点: http://www.npmjs.org/ 本文使用国内镜像地址: http://www.cnpmjs.org/ 搜索镜像:https://npm.taobao.org/ 具体方法: ...

  5. shiro英语

    Security Manager安全管理人员 Tutorial 辅导的 transient 短暂的 Cipher 密码 Memory 记忆 Access 访问Handy Hint 方便提示separa ...

  6. Android几种常见的多渠道(批量)打包方式介绍

    多渠道打包,主要是为了统计不同的渠道上包的下载数量,渠道越多,我们需要打的包数量越多,这个时候,我们没法去使用单纯的手动打包去一个一个的生成不同的渠道包,我们需要更高效的打包方式. 声明渠道方式一: ...

  7. 【python】数组去重

    直接用set就行,比如: l = [1, 1, 2, 2, 3, 4, 5] s = set(l) c = [i for i in s] print c 结果为: [1, 2, 3, 4, 5] 其中 ...

  8. OpenCV:OpenCV中的 parallel_for 和opencv parallel_for_

    OpenCV使用OMP完成并行运算,在使用AdaBoost检测的时候,在cascadedetect.cpp 里面,大量使用 parallel_for_(Range(0, stripCount), Ca ...

  9. jq 获取表单所有数据

    <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title&g ...

  10. 连接(JOIN)运算

    内连接--INNER JOIN 此处用商品表(product)和商店商品表(ShopProduct)测试,外键:product_id select sp.shop_id, sp.shop_name, ...