hdu2457
AC自动机+DP
#include <cstdio>
#include <queue>
#include <cstring>
using namespace std; #define D(x) const int MAX_D_LEN = ;
const int MAX_LEN = ;
const int MAX_N = ;
const int MAX_CHILD_NUM = ;
const int MAX_NODE_NUM = MAX_N * MAX_D_LEN;
const int INF = 0x3f3f3f3f; char dna[MAX_LEN]; struct Trie
{
int next[MAX_NODE_NUM][MAX_CHILD_NUM];
int fail[MAX_NODE_NUM];
bool disease[MAX_NODE_NUM];
int node_cnt;
bool vis[MAX_NODE_NUM]; //set it to false
int root;
int dp[MAX_LEN][MAX_NODE_NUM]; void init()
{
node_cnt = ;
root = newnode();
memset(vis, , sizeof(vis));
} int newnode()
{
for (int i = ; i < MAX_CHILD_NUM; i++)
next[node_cnt][i] = -;
disease[node_cnt++] = false;
return node_cnt - ;
} int get_id(char a)
{
if (a == 'A')
return ;
if (a == 'T')
return ;
if (a == 'C')
return ;
return ;
} void insert(char buf[])
{
int now = root;
for (int i = ; buf[i]; i++)
{
int id = get_id(buf[i]);
if (next[now][id] == -)
next[now][id] = newnode();
now = next[now][id];
}
disease[now] = true;
} void build()
{
queue<int>Q;
fail[root] = root;
for (int i = ; i < MAX_CHILD_NUM; i++)
if (next[root][i] == -)
next[root][i] = root;
else
{
fail[next[root][i]] = root;
Q.push(next[root][i]);
}
while (!Q.empty())
{
int now = Q.front();
Q.pop();
for (int i = ; i < MAX_CHILD_NUM; i++)
if (next[now][i] == -)
next[now][i] = next[fail[now]][i];
else
{
fail[next[now][i]]=next[fail[now]][i];
if (disease[fail[next[now][i]]])
disease[next[now][i]] = true;
Q.push(next[now][i]);
}
}
} int work()
{
scanf("%s", dna);
int len = strlen(dna);
for (int i = ; i < node_cnt; i++)
{
if (disease[i])
dp[len][i] = INF;
else
dp[len][i] = ;
}
for (int i = len - ; i >= ; i--)
{
int key = get_id(dna[i]);
for (int j = ; j < node_cnt; j++)
{
dp[i][j] = INF;
if (disease[j])
continue;
for (int k = ; k < ; k++)
{
int temp = ;
if (k == key)
temp = ;
int v = next[j][k];
if (disease[v])
continue;
dp[i][j] = min(dp[i][j], temp + dp[i + ][v]);
D(printf("%d\n", dp[i + ][next[j][k]]));
}
D(printf("dp[%d][%d]=%d\n", i, j, dp[i][j]));
}
}
return dp[][root];
} void debug()
{
for(int i = ;i < node_cnt;i++)
{
printf("id = %3d,fail = %3d,end = %3d,chi = [",i,fail[i],disease[i]);
for(int j = ;j < MAX_CHILD_NUM;j++)
printf("%2d",next[i][j]);
printf("]\n");
}
}
}ac; int n;
char st[MAX_D_LEN]; int main()
{
int case_num = ;
while (scanf("%d", &n), n)
{
ac.init();
for (int i = ; i < n; i++)
{
scanf("%s", st);
ac.insert(st);
}
ac.build();
int ans = ac.work();
if (ans >= INF)
ans = -;
printf("Case %d: %d\n", case_num++, ans);
}
return ;
}
hdu2457的更多相关文章
- hdu2457 Trie图+dp
hdu2457 给定n个模式串, 和一个文本串 问如果修改最少的字符串使得文本串不包含模式串, 输出最少的次数,如果不能修改成功,则输出-1 dp[i][j] 表示长度为i的字符串, 到达状态j(Tr ...
- HDU2457 DNA repair —— AC自动机 + DP
题目链接:https://vjudge.net/problem/HDU-2457 DNA repair Time Limit: 5000/2000 MS (Java/Others) Memory ...
- HDU2457 DNA repair(AC自动机+DP)
题目一串DNA最少需要修改几个基因使其不包含一些致病DNA片段. 这道题应该是AC自动机+DP的入门题了,有POJ2778基础不难写出来. dp[i][j]表示原DNA前i位(在AC自动机上转移i步) ...
- hdu2457:DNA repair
AC自动机+dp.问改变多少个字符能让目标串不含病毒串.即走过多少步不经过病毒串终点.又是同样的问题. #include<cstdio> #include<cstring> # ...
- [hdu2457]DNA repair(AC自动机+dp)
题意:给出一些不合法的模式DNA串,给出一个原串,问最少需要修改多少个字符,使得原串中不包含非法串. 解题关键:多模式串匹配->AC自动机,求最优值->dp,注意在AC自动机上dp的套路. ...
- 【hdu2457】ac自动机 + dp
传送门 题目大意: 给你一个字符主串和很多病毒串,要求更改最少的字符使得没有一个病毒串是主串的子串. 题解: ac自动机 + dp,用病毒串建好ac自动机,有毒的末尾flag置为true 构建fail ...
- hdu2457(最少替换多少个字符使主串不包含模式串)ac自动机+dp
题:http://acm.hdu.edu.cn/showproblem.php?pid=2457 题意:给定n个模式串,给定一个主串,问最替换掉多少个字符使主串不包含模式串或输出“-1”表示没有可行的 ...
- POJ 1625 Censored!(AC自动机->指针版+DP+大数)题解
题目:给你n个字母,p个模式串,要你写一个长度为m的串,要求这个串不能包含模式串,问你这样的串最多能写几个 思路:dp+AC自动机应该能看出来,万万没想到这题还要加大数...orz 状态转移方程dp[ ...
- Hnu 11187 Emoticons :-) (ac自己主动机+贪心)
题目大意: 破坏文本串.使之没有没有出现表情.破坏就是用空格替换.问最少须要破坏多少个字符. 思路分析: 初看跟Hdu 2457 没什么差别,事实上Hdu2457是要求将字符替换成ACGT,而这个仅仅 ...
随机推荐
- 软删除脏数据job笔记
某次处理一个case,发现线上库里有很多数据有问题.于是决定写一个job来将有问题的数据软删除掉.涉及到的两条SQL语句如下: <select id="loadTSKTVBillDai ...
- 【11-01】Sublime text 学习笔记
>>>快捷键 CTRL+P ->根据文件名打开文件 “# 标识”“:行号” Ctrl+Shift+P -> 打开Package Control Ctrl+R ->查 ...
- MySQL中MAX函数与Group By一起使用的注意事项(转)
mysql> select * from test; +----+-------+------+-------+ | id | name | age | class | +----+------ ...
- Memcached存储命令 - set
Memcached set 命令用于将 value(数据值) 存储在指定的 key(键) 中. 如果set的key已经存在,该命令可以更新该key所对应的原来的数据,也就是实现更新的作用. set 命 ...
- hdu4782 Beautiful Soup (模拟)
http://acm.hdu.edu.cn/showproblem.php?pid=4782 2013成都区域赛全题PDF:http://acm.hdu.edu.cn/downloads/2013Ch ...
- for 循环中 i++和 ++i
在标准C语言中, i++和 ++i的区别显而易见. 但是,当在for循环中使用 i++和 ++i的时候,会发现.只要这两种语句不用来赋值操作(作为右值,赋值给左值),那么这两种写法其实是一样的. fo ...
- BufferedReader readLine()方法
控制台输入字符串之后回车,后台接收传来的字符串,代码如下: import java.io.BufferedReader; import java.io.IOException; import java ...
- AngularJS API之toJson 对象转为JSON
toJson()能把对象序列化为json 方法讲解 这个方法最多支持2个参数: angular.toJson(obj, pretty); obj 是想要转换的对象, pretty 可以调节格式化的样式 ...
- 【C语言入门教程】5.4 递归
递归函数 是能够直接或通过另一个函数间接调用自身的函数,调用自身的方法称为递归调用.递归调用的本质是使用同一算法将复杂的问题不断化简,直到该问题解决. 例如求斐波那契数列的某一项算法适用于递归函数实现 ...
- EasyUI中datagrid控件的使用 设置多行表头(两行或多行)
EasyUI中的datagrid控件十分强大,能生成各种复杂的报表,现在因为项目需要,需要生成一个表头两行的表,找了一些说明文档,以下用一个实例来说明一下: 第一种方法: $('#divData'). ...