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的更多相关文章

  1. hdu2457 Trie图+dp

    hdu2457 给定n个模式串, 和一个文本串 问如果修改最少的字符串使得文本串不包含模式串, 输出最少的次数,如果不能修改成功,则输出-1 dp[i][j] 表示长度为i的字符串, 到达状态j(Tr ...

  2. HDU2457 DNA repair —— AC自动机 + DP

    题目链接:https://vjudge.net/problem/HDU-2457 DNA repair Time Limit: 5000/2000 MS (Java/Others)    Memory ...

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

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

  4. hdu2457:DNA repair

    AC自动机+dp.问改变多少个字符能让目标串不含病毒串.即走过多少步不经过病毒串终点.又是同样的问题. #include<cstdio> #include<cstring> # ...

  5. [hdu2457]DNA repair(AC自动机+dp)

    题意:给出一些不合法的模式DNA串,给出一个原串,问最少需要修改多少个字符,使得原串中不包含非法串. 解题关键:多模式串匹配->AC自动机,求最优值->dp,注意在AC自动机上dp的套路. ...

  6. 【hdu2457】ac自动机 + dp

    传送门 题目大意: 给你一个字符主串和很多病毒串,要求更改最少的字符使得没有一个病毒串是主串的子串. 题解: ac自动机 + dp,用病毒串建好ac自动机,有毒的末尾flag置为true 构建fail ...

  7. hdu2457(最少替换多少个字符使主串不包含模式串)ac自动机+dp

    题:http://acm.hdu.edu.cn/showproblem.php?pid=2457 题意:给定n个模式串,给定一个主串,问最替换掉多少个字符使主串不包含模式串或输出“-1”表示没有可行的 ...

  8. POJ 1625 Censored!(AC自动机->指针版+DP+大数)题解

    题目:给你n个字母,p个模式串,要你写一个长度为m的串,要求这个串不能包含模式串,问你这样的串最多能写几个 思路:dp+AC自动机应该能看出来,万万没想到这题还要加大数...orz 状态转移方程dp[ ...

  9. Hnu 11187 Emoticons :-) (ac自己主动机+贪心)

    题目大意: 破坏文本串.使之没有没有出现表情.破坏就是用空格替换.问最少须要破坏多少个字符. 思路分析: 初看跟Hdu 2457 没什么差别,事实上Hdu2457是要求将字符替换成ACGT,而这个仅仅 ...

随机推荐

  1. verilog描述表决器的两种方式简易分析

    命题:设计一个三变量表决器.真值表如下: 可以写出并简化得出公式:F=AB+BC+AC. 以下是两种算法: 第一种:仅从算法方面描述为:A.B.C的和大于1则输出结果为1,否则为0:源码如下: mod ...

  2. 安装好Android Studio(如果内存足够可以改下as的内存)

    找到studio的bin目录,找到如下文件

  3. 收到的电邮附件为Winmail.dat?

    以下信息来源于微软帮助中心:您收到电子邮件,其中包含一个 winmail.dat 的附件.电子邮件被人使用的 Microsoft Outlook 发送给您.该邮件的格式是丰富文本格式 (RTF). 原 ...

  4. WP8微信5.3开始内测 支持Cortana语音 两微破冰了?

    WP版微信v5.3内测版昨发布了,进行了一些小幅升级,最意外的是原生支持WP8.1版Cortana语音命令操作.要知道微软的聊天机器人“小冰”在微信上存在不到4天,就被微信全面封杀退出,现在微信又内测 ...

  5. 天翼宽带政企网关B2-1P 如何获得超级管理员账号?

    RT 用useradmin没办法做NAT,想进telecomadmin里面看看,,,,,并且已经使用过nE7jA%5m这个密码登录,没有用! 求办法!!! 最佳答案 查找超级管理员密码方法: 1.用光 ...

  6. Ubuntu 14 安装 “宋体,微软雅黑,WPS Office的symbol、wingdings、wingdings 2、wingdings 3、webding字体,Consolas雅黑混合版编程字体” 等 Windows 7 下的字体

    Windows平台下,“宋体”.“微软雅黑”.“Courier New(编程字体)”用的比较多,看的也习惯了.那如何在 Ubuntu下也安装这些字体呢? 操作步骤如下: 第一步:从 Windows 7 ...

  7. 学C++50条建议

    1.把C++当成一门新的语言学习(和C没啥关系!真的.): 2.看<Thinking In C++>,不要看<C++变成死相>: 3.看<The C++ Programm ...

  8. Flash+XML前后按钮超酷焦点图,层叠翻转图形

    Flash+XML,有“前后”按钮,可以左右点击,支持鼠标滚轮,效果流畅,推荐下载.大图尺寸:680x345 点击下载

  9. 网页兼容浏览器测试工具Multibrowser

    网页兼容性测试工具(MultiBrowser),有firefox,chrome,IE 下载

  10. HDU 5384 字典树、AC自动机

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=5384 用字典树.AC自动机两种做法都可以做 #include<stdio.h> #includ ...