hdu2457(最少替换多少个字符使主串不包含模式串)ac自动机+dp
题: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
- #include<iostream>
- #include<cstdio>
- #include<algorithm>
- #include<cstring>
- #include<queue>
- using namespace std;
- typedef long long ll;
- const int M=2e3+;
- const int maxn=;
- const int inf=0x3f3f3f3f;
- int dp[M][M];
- char s[M];
- struct ac{
- int trie[M][maxn],fail[M];
- bool end[M];
- int tot,root;
- int newnode(){
- for(int i=;i<maxn;i++)
- trie[tot][i]=-;
- end[tot++]=;
- return tot-;
- }
- void init(){
- memset(end,false,sizeof(end));
- tot=;
- root=newnode();
- }
- int getid(char c){
- if(c=='A')
- return ;
- if(c=='G')
- return ;
- if(c=='T')
- return ;
- if(c=='C')
- return ;
- }
- void insert(char buf[]){
- int now=root,len=strlen(buf);
- for(int i=;i<len;i++){
- int id=getid(buf[i]);
- if(trie[now][id]==-)
- trie[now][id]=newnode();
- now=trie[now][id];
- }
- end[now]=true;
- }
- void getfail(){
- queue<int>que;
- while(!que.empty())
- que.pop();
- fail[root]=root;
- for(int i=;i<maxn;i++){
- if(trie[root][i]==-)
- trie[root][i]=root;
- else{
- fail[trie[root][i]]=root;
- que.push(trie[root][i]);
- }
- }
- while(!que.empty()){
- int now=que.front();
- que.pop();
- if(end[fail[now]])
- end[now]=true;
- for(int i=;i<maxn;i++){
- if(trie[now][i]!=-){
- fail[trie[now][i]]=trie[fail[now]][i];
- que.push(trie[now][i]);
- }
- else
- trie[now][i]=trie[fail[now]][i];
- }
- }
- }
- }AC;
- int main(){
- int n,t=;
- while(~scanf("%d",&n)&&n){
- AC.init();
- for(int i=;i<n;i++){
- scanf("%s",s);
- AC.insert(s);
- }
- AC.getfail();
- scanf("%s",s);
- int len=strlen(s);
- for(int i=;i<=len;i++)
- for(int j=;j<AC.tot;j++)
- dp[i][j]=inf;
- dp[][AC.root]=;
- for(int i=;i<len;i++)
- for(int j=;j<AC.tot;j++)
- if(dp[i][j]<inf){
- for(int k=;k<maxn;k++){
- int now=AC.trie[j][k];
- if(AC.end[now])
- continue;
- // cout<<now<<"!!"<<endl;
- int id=AC.getid(s[i]);
- int add=;
- if(id!=k)
- add++;
- dp[i+][now]=min(dp[i+][now],dp[i][j]+add);
- // cout<<dp[i+1][now];
- }
- }
- int ans=inf;
- for(int i=;i<AC.tot;i++){
- ans=min(ans,dp[len][i]);
- }
- printf("Case %d: ",++t);
- if(ans==inf)
- puts("-1");
- else
- printf("%d\n",ans);
- }
- return ;
- }
hdu2457(最少替换多少个字符使主串不包含模式串)ac自动机+dp的更多相关文章
- 【hdu2457】ac自动机 + dp
传送门 题目大意: 给你一个字符主串和很多病毒串,要求更改最少的字符使得没有一个病毒串是主串的子串. 题解: ac自动机 + dp,用病毒串建好ac自动机,有毒的末尾flag置为true 构建fail ...
- HDU2457 DNA repair(AC自动机+DP)
题目一串DNA最少需要修改几个基因使其不包含一些致病DNA片段. 这道题应该是AC自动机+DP的入门题了,有POJ2778基础不难写出来. dp[i][j]表示原DNA前i位(在AC自动机上转移i步) ...
- [hdu2457]DNA repair(AC自动机+dp)
题意:给出一些不合法的模式DNA串,给出一个原串,问最少需要修改多少个字符,使得原串中不包含非法串. 解题关键:多模式串匹配->AC自动机,求最优值->dp,注意在AC自动机上dp的套路. ...
- HDU2457 DNA repair —— AC自动机 + DP
题目链接:https://vjudge.net/problem/HDU-2457 DNA repair Time Limit: 5000/2000 MS (Java/Others) Memory ...
- linux(centos8):用tr替换或删除字符
一,tr命令的用途 tr命令可以替换或删除文件中的字符 它从标准输入设备读取数据, 处理完成将结果输出到标准输出设备 说明:刘宏缔的架构森林是一个专注架构的博客,地址:https://www.cnbl ...
- poj 3352 Road Construction【边双连通求最少加多少条边使图双连通&&缩点】
Road Construction Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 10141 Accepted: 503 ...
- 【Linux基础】tr命令替换和删除字符
1.tr命令 tr可以对来自标准输入的字符进行替换.压缩和删除,可以将一组字符变成另外一组字符.通过使用 tr,您可以非常容易地实现 sed 的许多最基本功能.您可以将 tr 看作为 sed 的(极其 ...
- vim的全局替换[zz]&把字符替换成回车
本文出自 http://blog.csdn.net/shuangde800 本文是在学习<使用vi编辑器, Lamb & Robbins编著>时在所记的笔记. 本文内容 ...
- mysql主从怎么样使主为innodb辅为myisam
MySQL主从复制(linux主+windows从) http://blog.csdn.net/qq_20032995/article/details/54380290 mysql主从怎么样使主为in ...
随机推荐
- ArcGIS二次开发的几种方式
1.ArcEngine开发 二次开发的常用方式,开发提供接口齐全,功能强大,比较成熟.但是,开发的软件使用需要指定版本的运行环境才能运行. 2.Addin开发 二次开发与ArcMap嵌入,开发方便,可 ...
- NO8 find结合sed查找替换企业案例多方法精讲&命令总结!
·sed #替换 eg: sed 'sed 's#已有的内容#更改的内容#g' oldboy.txt s 代表替换,g代表全局,sg就是全局替换 ...
- C# OBJ模型解析的封装(网上看到的保留一份)
/// <author>Lukas Eibensteiner</author> /// <date>19.02.2013</date> /// < ...
- Hash!
Panda一个字符串是否是另一个字符串的子串 #include<bits/stdc++.h> using namespace std; const int mod=998244353,tt ...
- spring-@ResponseBody返回时的编码处理
下面是一个解决方案 @RequestMapping(value = "/queryall", method = GET, produces = "application/ ...
- Java语言学习总结 扩展篇 包装类的概念及其使用
包装类 包装类的概述 Java提供了两个类型系统,基本类型与引用类型,使用基本类型在于效率,然而很多情况,会创建对象使用,因为对象可以做更多的功能,如果想要我们的基本类型像对象一样操作,就可以使用基本 ...
- Java对象序列化输入输出
在网上看到一篇有关于对象序列化的代码,自己仿着写了把 在Java中,entity通过implements Serializable,然后使用ObjectInputStream和ObjectOutput ...
- 吴裕雄--天生自然C++语言学习笔记:C++ 日期 & 时间
C++ 标准库没有提供所谓的日期类型.C++ 继承了 C 语言用于日期和时间操作的结构和函数.为了使用日期和时间相关的函数和结构,需要在 C++ 程序中引用 <ctime> 头文件. 有四 ...
- Mysql升级、免安装版MYSQL安装与卸载
1. 备份好数据库:表结构和数据: 2. 备份my.ini文件和data文件夹: 3. 卸载旧版本mysql: 4. 安装新版本mysq ...
- 第十五篇 用户认证auth
用户认证auth 阅读目录(Content) 用户认证 auth模块 1 .authenticate() 2 .login(HttpRequest, user) 3 .logout(request) ...