题:http://acm.hdu.edu.cn/showproblem.php?pid=2457

题意:给定n个模式串,给定一个主串,问最替换掉多少个字符使主串不包含模式串或输出“-1”表示没有可行的方案;

分析:给n个模式串建立ac自动机,考虑dp[i][j],表示长度为 i , j 节点变换为主串前 i 个的最小操作数,j节点要转换必须使当前节点为“安全点”,即end[trie[i][j]]==0;

   dp转化就只要不是自己就要在转移过程中+1,i 位置取min 给下一位i+1

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<algorithm>
  4. #include<cstring>
  5. #include<queue>
  6. using namespace std;
  7. typedef long long ll;
  8. const int M=2e3+;
  9. const int maxn=;
  10. const int inf=0x3f3f3f3f;
  11. int dp[M][M];
  12. char s[M];
  13. struct ac{
  14. int trie[M][maxn],fail[M];
  15. bool end[M];
  16. int tot,root;
  17. int newnode(){
  18. for(int i=;i<maxn;i++)
  19. trie[tot][i]=-;
  20. end[tot++]=;
  21. return tot-;
  22. }
  23. void init(){
  24. memset(end,false,sizeof(end));
  25. tot=;
  26. root=newnode();
  27. }
  28. int getid(char c){
  29. if(c=='A')
  30. return ;
  31. if(c=='G')
  32. return ;
  33. if(c=='T')
  34. return ;
  35. if(c=='C')
  36. return ;
  37. }
  38. void insert(char buf[]){
  39. int now=root,len=strlen(buf);
  40. for(int i=;i<len;i++){
  41. int id=getid(buf[i]);
  42. if(trie[now][id]==-)
  43. trie[now][id]=newnode();
  44. now=trie[now][id];
  45. }
  46. end[now]=true;
  47. }
  48. void getfail(){
  49. queue<int>que;
  50. while(!que.empty())
  51. que.pop();
  52. fail[root]=root;
  53. for(int i=;i<maxn;i++){
  54. if(trie[root][i]==-)
  55. trie[root][i]=root;
  56. else{
  57. fail[trie[root][i]]=root;
  58. que.push(trie[root][i]);
  59. }
  60. }
  61. while(!que.empty()){
  62. int now=que.front();
  63. que.pop();
  64. if(end[fail[now]])
  65. end[now]=true;
  66. for(int i=;i<maxn;i++){
  67. if(trie[now][i]!=-){
  68. fail[trie[now][i]]=trie[fail[now]][i];
  69. que.push(trie[now][i]);
  70. }
  71. else
  72. trie[now][i]=trie[fail[now]][i];
  73. }
  74. }
  75. }
  76. }AC;
  77. int main(){
  78. int n,t=;
  79. while(~scanf("%d",&n)&&n){
  80. AC.init();
  81. for(int i=;i<n;i++){
  82. scanf("%s",s);
  83. AC.insert(s);
  84. }
  85. AC.getfail();
  86.  
  87. scanf("%s",s);
  88. int len=strlen(s);
  89. for(int i=;i<=len;i++)
  90. for(int j=;j<AC.tot;j++)
  91. dp[i][j]=inf;
  92. dp[][AC.root]=;
  93. for(int i=;i<len;i++)
  94. for(int j=;j<AC.tot;j++)
  95. if(dp[i][j]<inf){
  96. for(int k=;k<maxn;k++){
  97. int now=AC.trie[j][k];
  98. if(AC.end[now])
  99. continue;
  100. // cout<<now<<"!!"<<endl;
  101. int id=AC.getid(s[i]);
  102. int add=;
  103. if(id!=k)
  104. add++;
  105. dp[i+][now]=min(dp[i+][now],dp[i][j]+add);
  106. // cout<<dp[i+1][now];
  107. }
  108. }
  109. int ans=inf;
  110. for(int i=;i<AC.tot;i++){
  111. ans=min(ans,dp[len][i]);
  112.  
  113. }
  114.  
  115. printf("Case %d: ",++t);
  116. if(ans==inf)
  117. puts("-1");
  118. else
  119. printf("%d\n",ans);
  120. }
  121. return ;
  122. }

hdu2457(最少替换多少个字符使主串不包含模式串)ac自动机+dp的更多相关文章

  1. 【hdu2457】ac自动机 + dp

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

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

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

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

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

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

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

  5. linux(centos8):用tr替换或删除字符

    一,tr命令的用途 tr命令可以替换或删除文件中的字符 它从标准输入设备读取数据, 处理完成将结果输出到标准输出设备 说明:刘宏缔的架构森林是一个专注架构的博客,地址:https://www.cnbl ...

  6. poj 3352 Road Construction【边双连通求最少加多少条边使图双连通&&缩点】

    Road Construction Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 10141   Accepted: 503 ...

  7. 【Linux基础】tr命令替换和删除字符

    1.tr命令 tr可以对来自标准输入的字符进行替换.压缩和删除,可以将一组字符变成另外一组字符.通过使用 tr,您可以非常容易地实现 sed 的许多最基本功能.您可以将 tr 看作为 sed 的(极其 ...

  8. vim的全局替换[zz]&把字符替换成回车

    本文出自   http://blog.csdn.net/shuangde800   本文是在学习<使用vi编辑器, Lamb & Robbins编著>时在所记的笔记.   本文内容 ...

  9. mysql主从怎么样使主为innodb辅为myisam

    MySQL主从复制(linux主+windows从) http://blog.csdn.net/qq_20032995/article/details/54380290 mysql主从怎么样使主为in ...

随机推荐

  1. ArcGIS二次开发的几种方式

    1.ArcEngine开发 二次开发的常用方式,开发提供接口齐全,功能强大,比较成熟.但是,开发的软件使用需要指定版本的运行环境才能运行. 2.Addin开发 二次开发与ArcMap嵌入,开发方便,可 ...

  2. NO8 find结合sed查找替换企业案例多方法精讲&命令总结!

    ·sed    #替换  eg: sed 'sed 's#已有的内容#更改的内容#g' oldboy.txt                   s 代表替换,g代表全局,sg就是全局替换       ...

  3. C# OBJ模型解析的封装(网上看到的保留一份)

    /// <author>Lukas Eibensteiner</author> /// <date>19.02.2013</date> /// < ...

  4. Hash!

    Panda一个字符串是否是另一个字符串的子串 #include<bits/stdc++.h> using namespace std; const int mod=998244353,tt ...

  5. spring-@ResponseBody返回时的编码处理

    下面是一个解决方案 @RequestMapping(value = "/queryall", method = GET, produces = "application/ ...

  6. Java语言学习总结 扩展篇 包装类的概念及其使用

    包装类 包装类的概述 Java提供了两个类型系统,基本类型与引用类型,使用基本类型在于效率,然而很多情况,会创建对象使用,因为对象可以做更多的功能,如果想要我们的基本类型像对象一样操作,就可以使用基本 ...

  7. Java对象序列化输入输出

    在网上看到一篇有关于对象序列化的代码,自己仿着写了把 在Java中,entity通过implements Serializable,然后使用ObjectInputStream和ObjectOutput ...

  8. 吴裕雄--天生自然C++语言学习笔记:C++ 日期 & 时间

    C++ 标准库没有提供所谓的日期类型.C++ 继承了 C 语言用于日期和时间操作的结构和函数.为了使用日期和时间相关的函数和结构,需要在 C++ 程序中引用 <ctime> 头文件. 有四 ...

  9. Mysql升级、免安装版MYSQL安装与卸载

    1.         备份好数据库:表结构和数据: 2.         备份my.ini文件和data文件夹: 3.         卸载旧版本mysql: 4.         安装新版本mysq ...

  10. 第十五篇 用户认证auth

    用户认证auth 阅读目录(Content) 用户认证 auth模块 1 .authenticate() 2 .login(HttpRequest, user) 3 .logout(request) ...