传送门

题目大意:

给你一个字符主串和很多病毒串,要求更改最少的字符使得没有一个病毒串是主串的子串。

题解:

ac自动机 + dp,用病毒串建好ac自动机,有毒的末尾flag置为true

构建fail指针时,如果fail指针所指节点flag=true,则将当前节点的flag也置为true。

用dp[i][j]表示长度为i的字符串匹配到j节点时最少的更改次数。

这样在ac自动机上跑,若该节点与原串的字符不同则+1

否则+0. 最后扫一遍取flag!=true的dp[len][...]的最小值。

code

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstring>
using namespace std; const int N = 55, L = 25, OO = 0x3f3f3f3f;
int n, dp[1005][N * L], tot, len, Case;
char t[L], s[1005]; struct node{
int trans[5], fail;
bool flag;
inline void clear(){
memset(trans, 0, sizeof trans);
flag = fail = 0;
}
}trie[N * L]; inline int getVal(char p){
if(p == 'A') return 1;
else if(p == 'C') return 2;
else if(p == 'G') return 3;
else return 4;
} inline void insert(){
int pos = 1;
len = strlen(t + 1);
for(int i = 1; i <= len; i++){
if(!trie[pos].trans[getVal(t[i])])
trie[trie[pos].trans[getVal(t[i])] = ++tot].clear();
pos = trie[pos].trans[getVal(t[i])];
}
trie[pos].flag = true;
} inline void buildFail(){
for(int i = 1; i <= 4; i++) trie[0].trans[i] = 1;
static int que[N * L], qn;
que[qn = 1] = 1;
for(int ql = 1; ql <= qn; ql++){
int u = que[ql], v, w;
for(int i = 1; i <= 4; i++){
v = trie[u].fail;
while(!trie[v].trans[i]) v = trie[v].fail;
v = trie[v].trans[i];
w = trie[u].trans[i];
if(w){
trie[w].fail = v, que[++qn] = w;
if(trie[v].flag)
trie[w].flag = true;
}
else trie[u].trans[i] = v;
}
}
} inline void solve(){
len = strlen(s + 1); for(int i = 1; i <= len; i++)
for(int j = 1; j <= tot; j++)
dp[i][j] = OO;
dp[0][1] = 0;
for(int i = 1; i <= len; i++)
for(int j = 1; j <= tot; j++){
if(dp[i - 1][j] == OO) continue;
for(int k = 1; k <= 4; k++){
int u = trie[j].trans[k];
if(trie[u].flag) continue;
dp[i][u] = min(dp[i][u], dp[i - 1][j] + (getVal(s[i]) != k));
}
}
int ans = OO;
for(int i = 1; i <= tot; i++){
if(dp[len][i] == OO) continue;
ans = min(ans, dp[len][i]);
}
printf("Case %d: %d\n", ++Case, ans < OO ? ans: -1);
} int main(){
while(scanf("%d", &n), n){
trie[tot = 1].clear();
for(int i = 1; i <= n; i++){
scanf("%s", t + 1);
insert();
}
buildFail();
scanf("%s", s + 1);
solve();
}
return 0;
}

【hdu2457】ac自动机 + dp的更多相关文章

  1. HDU2457 DNA repair(AC自动机+DP)

    题目一串DNA最少需要修改几个基因使其不包含一些致病DNA片段. 这道题应该是AC自动机+DP的入门题了,有POJ2778基础不难写出来. dp[i][j]表示原DNA前i位(在AC自动机上转移i步) ...

  2. POJ1625 Censored!(AC自动机+DP)

    题目问长度m不包含一些不文明单词的字符串有多少个. 依然是水水的AC自动机+DP..做完后发现居然和POJ2778是一道题,回过头来看都水水的... dp[i][j]表示长度i(在自动机转移i步)且后 ...

  3. HDU2296 Ring(AC自动机+DP)

    题目是给几个带有价值的单词.而一个字符串的价值是 各单词在它里面出现次数*单词价值 的和,问长度不超过n的最大价值的字符串是什么? 依然是入门的AC自动机+DP题..不一样的是这题要输出具体方案,加个 ...

  4. hdu 4117 GRE Words AC自动机DP

    题目:给出n个串,问最多能够选出多少个串,使得前面串是后面串的子串(按照输入顺序) 分析: 其实这题是这题SPOJ 7758. Growing Strings AC自动机DP的进阶版本,主题思想差不多 ...

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

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

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

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

  7. HDU2296——Ring(AC自动机+DP)

    题意:输入N代表字符串长度,输入M代表喜欢的词语的个数,接下来是M个词语,然后是M个词语每个的价值.求字符串的最大价值.每个单词的价值就是单价*出现次数.单词可以重叠.如果不止一个答案,选择字典序最小 ...

  8. tyvj P1519 博彩游戏(AC自动机+DP滚动数组)

    P1519 博彩游戏 背景 Bob最近迷上了一个博彩游戏…… 描述 这个游戏的规则是这样的:每花一块钱可以得到一个随机数R,花上N块钱就可以得到一个随机序列:有M个序列,如果某个序列是产生的随机序列的 ...

  9. bzoj 1030 [JSOI2007]文本生成器(AC自动机+DP)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1030 [题意] 给n个小串,随机构造一个长为m的大串,一个串合法当且仅当包含一个或多个 ...

随机推荐

  1. 本文介绍C# BitmapData

    本文介绍C# BitmapData,对于C# BitmapData,虽然BitmapData.Width还是等于Bitmap.Width,但大概是出于显示性能的考虑.   最近要转开发平台,正研究C# ...

  2. VC++ 6.0 BUG BUG BUG BUG BUG

    http://blog.163.com/amao831@126/blog/#m=0 我经常在的VC++6.0中 定义某个类的对象时 再用.访问或者->访问时不自动弹出他的成员函数或者成员变量 最 ...

  3. 【例题 7-13 UVA-1374】Power Calculus

    [链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 结论:每次只用新生成的数字就好了. 然后就是IDA*了. 迭代深搜+剪枝. [代码] /* 1.Shoud it use long ...

  4. valueof(), intvalue(0 parseint() 这三个方法怎么用

    valueOf(int i) 返回一个表示指定的 int 值的 Integer 实例.valueOf(String s) 返回保存指定的 String 的值的 Integer 对象.valueOf(S ...

  5. 【部分原创】python实现视频内的face swap(换脸)

    1.准备工作,按博主的环境为准 Python 3.5 Opencv 3 Tensorflow 1.3.1 Keras 2 cudnn和CUDA,如果你的GPU足够厉害并且支持的话,可以选择安装 那就先 ...

  6. log4j 2.x 版本的 properties 配置

    #用于设置log4j2自身内部的信息输出,可以不设置,当设置成trace时,会看到log4j2内部各种详细输出status = debugdest = errname = PropertiesConf ...

  7. @EnableAsync和@Async开始异步任务支持

    Spring通过任务执行器(TaskExecutor)来实现多线程和并发编程.使用ThreadPoolTaskExecutor可实现一个基于线程池的TaskExecutor.在开发中实现异步任务,我们 ...

  8. Spring资源抽象Resource

    JDK操纵底层资源基本就是 java.net.URL .java.io.File .java.util.Properties这些.取资源基本是根据绝对路径或当前类的相对路径来取.从类路径或Web容器上 ...

  9. ZOJ 1494 Climbing Worm 数学水题

    http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=494 题目大意: 一只蜗牛要从爬上n英寸高的地方,他速度为u每分钟,他爬完u需要 ...

  10. 4、linux下应用创建线程

    1.linux创建线程之pthread_create 函数简介 pthread_create是UNIX环境创建线程函数 头文件 #include<pthread.h> 函数声明 int p ...