【hdu2457】ac自动机 + dp
题目大意:
给你一个字符主串和很多病毒串,要求更改最少的字符使得没有一个病毒串是主串的子串。
题解:
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的更多相关文章
- HDU2457 DNA repair(AC自动机+DP)
题目一串DNA最少需要修改几个基因使其不包含一些致病DNA片段. 这道题应该是AC自动机+DP的入门题了,有POJ2778基础不难写出来. dp[i][j]表示原DNA前i位(在AC自动机上转移i步) ...
- POJ1625 Censored!(AC自动机+DP)
题目问长度m不包含一些不文明单词的字符串有多少个. 依然是水水的AC自动机+DP..做完后发现居然和POJ2778是一道题,回过头来看都水水的... dp[i][j]表示长度i(在自动机转移i步)且后 ...
- HDU2296 Ring(AC自动机+DP)
题目是给几个带有价值的单词.而一个字符串的价值是 各单词在它里面出现次数*单词价值 的和,问长度不超过n的最大价值的字符串是什么? 依然是入门的AC自动机+DP题..不一样的是这题要输出具体方案,加个 ...
- 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的大串,一个串合法当且仅当包含一个或多个 ...
随机推荐
- 跟我一起学extjs5(42--单个模块的数据新增方式)
跟我一起学extjs5(42--单个模块的数据新增方式) 前面的章节中已经增加了一个自己定义的模块,而且能够进行数据的新增.改动.删除的操作了,在这个基础上就能够大作文章了. 这一节来 ...
- 三个水杯(BFS)
三个水杯 时间限制:1000 ms | 内存限制:65535 KB 难度:4 描写叙述 给出三个水杯.大小不一,而且仅仅有最大的水杯的水是装满的,其余两个为空杯子. 三个水杯之间相互倒水,而且水杯 ...
- Android 自己定义主菜单
本文介绍一个超简单的自己定义主菜单.效果例如以下: 原理:事实上就是对原生的Dialog的一个简单的封装.并加上显示和隐藏的动画效果.再给控件加上回调事件. TestDialog.java publi ...
- 获取iOS顶部状态栏和Navigation的高度
状态栏的高度 20 [[UIApplication sharedApplication] statusBarFrame].size.height Navigation的高度 44 self.navig ...
- php websocket-网页实时聊天之PHP实现websocket(ajax长轮询和websocket都可以时间网络聊天室)
php websocket-网页实时聊天之PHP实现websocket(ajax长轮询和websocket都可以时间网络聊天室) 一.总结 1.ajax长轮询和websocket都可以时间网络聊天室 ...
- 使用maven进行测试设置断点调试的方法
在Maven中配置测试插件surefire来进行单元测试,默认情况下,surefire会执行文件名以Test开头或结尾的测试用例,或者是以TestCase结尾的测试用例. ...
- aspcms产品详情页调取相关产品
产品详情页调用相关产品最常见的应用就是装饰公司网站,设计师页面要求调取设计师做过的案例.aspcms本身有这个功能,但不能完全符合要求,看代码 {aspcms:content sort={aspcms ...
- POJ 3628 Bookshelf 2 0-1背包
传送门:http://poj.org/problem?id=3628 题目看了老半天,牛来叠罗汉- -|||和书架什么关系啊.. 大意是:一群牛来叠罗汉,求超过书架的最小高度. 0-1背包的问题,对于 ...
- C++中string类的操作函数。
相信使用过MFC编程的朋友对CString这个类的印象应该非常深刻吧?的确,MFC中的CString类使用起来真的非常的方便好用.但是如果离开了MFC框架,还有没有这样使用起来非常方便的类呢?答案是肯 ...
- 黑马程序猿-assign、retain、release、nonatomic、atomic、strong、weak
都是用于修饰@property声明的变量 assign:用于非oc对象类型,表示直接赋值(默认值) retain:用于mrc中,用于类属性中有oc对象的情况,表示先推断赋值的对象是否和实例对象变量的值 ...