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. Redis for .NET 系列之实现分页需求

    代码笔记: var tableName = "Table1"; redisClient.AddItemToSortedSet(tableName, ); redisClient.A ...

  2. fedora配置网络

    网络配置包括3个部分: ipadd的配置 gateway profile dns profile 格式区别: 1和2的格式都是: CONFIG_ITEM = value; 3的格式是: nameser ...

  3. 在Linux下和Windows下遍历目录的方法及如何达成一致性操作

    最近因为测试目的需要遍历一个目录下面的所有文件进行操作,主要是读每个文件的内容,只要知道文件名就OK了.在Java中直接用File类就可以搞定,因为Java中使用了组合模式,使得客户端对单个文件和文件 ...

  4. [译]Introducing ASP.NET 5

    原文:http://weblogs.asp.net/scottgu/introducing-asp-net-5 ASP.NET 5预览版发布了, 可以在这下载最新的Visual Studio 2015 ...

  5. Hdu.1325.Is It A Tree?(并查集)

    Is It A Tree? Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) To ...

  6. C#之类与对象

    这段代码告诉我们要把#define DEBUG放在文件的开头位置,不然会导致编译错误,最后还要#endif 以上代码告诉我们可以对自己创建的类设计自己的构造方法,然后可以通过具体的Main()函数来通 ...

  7. 请求WebMethod, Ajax 处理更加专注

    在WebForm下 开发ajax程序,需要借助于一般处理程序(*.ashx)或web服务(*.asmx),并且每一个ajax请求,都要建一个这样的文件,如此一来,如 果在一个项目中ajax程序多了,势 ...

  8. git之remote repository create(远程仓库创建)

    参考:Git教程 - 廖雪峰的官方网站 1.在Git bash窗口执行如下指令创建SSH KEY: ssh-keygen -t rsa -C "sunjf@biomarker.com.cn& ...

  9. Javascript高级程序设计——函数

    函数Function 通过函数封装多条语句,在任何地方执行.javascript函数不会重载,相同名字函数,名字属于后定义的函数通过function关键词声明. function functionNa ...

  10. 一个C#的与web服务器交互的HttpClient类

    using System; using System.Collections.Generic; using System.IO; using System.Text; using System.Net ...