poj 3691 DNA repair(AC自己主动机+dp)
DNA repair
Description Biologists finally invent techniques of repairing DNA that contains segments causing kinds of inherited diseases. For the sake of simplicity, a DNA is represented as a string containing characters 'A', 'G' , 'C' and 'T'. The repairing techniques are simply You are to help the biologists to repair a DNA by changing least number of characters. Input
The input consists of multiple test cases. Each test case starts with a line containing one integers N (1 ≤ N ≤ 50), which is the number of DNA segments causing inherited diseases.
The following N lines gives N non-empty strings of length not greater than 20 containing only characters in "AGCT", which are the DNA segments causing inherited disease. The last line of the test case is a non-empty string of length not greater than 1000 containing only characters in "AGCT", which is the DNA to be repaired. The last test case is followed by a line containing one zeros. Output
For each test case, print a line containing the test case number( beginning with 1) followed by the
number of characters which need to be changed. If it's impossible to repair the given DNA, print -1. Sample Input
Sample Output
Source |
题意:
给定N个模式串(1 ≤ N ≤ 50) 最大长度为20,一个主串(长最大为1000),同意涉及的字符为4个 {'A','T','G','C'},求最少改动几个字符 使主串不包括全部模式串。
思路:
对模式串建立AC自己主动机。依据AC自己主动机来dp。
dp[i][j]表示到主串第i个字符时到达自己主动机上第j个节点时改动最少字符数。
枚举下一个字符为AGCT中的一个来转移,注意转移的时候不能包括模式串中的节点,于是要用一个数组来记录该节点结尾时是否包括了单词。
代码:
- #include <cstdio>
- #include <cstring>
- #include <cstring>
- #include <algorithm>
- #include <queue>
- using namespace std;
- const int INF=0x3f3f3f3f;
- const int maxn=10010;
- const int bsz=26;
- typedef long long ll;
- char txt[maxn],cc[]="AGCT";
- bool vis[maxn];
- int ans;
- struct Trie
- {
- bool have[maxn]; // 该节点结尾是否包括单词
- int ch[maxn][bsz],val[maxn],sz,cnt[maxn]; // ch存Trie val-节点相应的单词 cnt-节点结尾单词个数
- int f[maxn],last[maxn];//f-失配指针 last-后缀链接
- int newnode()
- {
- val[sz]=0; cnt[sz]=0; have[sz]=0;
- memset(ch[sz],-1,sizeof ch[sz]);
- return sz++;
- }
- void init()
- {
- sz=0;
- newnode();
- }
- int idx(char c) // 取c的标号 详细看字符为什么
- {
- return c-'A';
- }
- void Insert(char *st,int id)
- {
- int u=0,n=strlen(st),c,i;
- for(i=0;i<n;i++)
- {
- c=idx(st[i]);
- if(ch[u][c]==-1)
- ch[u][c]=newnode();
- u=ch[u][c];
- }
- val[u]=id;
- cnt[u]++;
- have[u]=1;
- }
- void build()
- {
- int u=0,v,i;
- queue<int> q;
- f[0]=0;
- for(i=0;i<bsz;i++)
- {
- v=ch[u][i];
- if(v==-1) ch[u][i]=0;
- else
- {
- f[v]=0;
- q.push(v);
- }
- }
- while(!q.empty())
- {
- u=q.front();
- q.pop();
- last[u]=val[f[u]]?
- f[u]:last[f[u]];
- for(i=0;i<bsz;i++)
- {
- v=ch[u][i];
- if(v==-1) ch[u][i]=ch[f[u]][i]; // 将NULL变为有意义 沿着父亲失配指针走第一个有意义的节点
- else
- {
- f[v]=ch[f[u]][i];
- have[v]|=have[f[v]];
- q.push(v);
- }
- }
- }
- }
- bool Find(char *st,int m,int id)
- {
- int n=strlen(st),i,u=0,c,p,flag=0;
- // vis-可标记哪些单词出现过 相同的单词仅仅标记一个
- for(i=0;i<n;i++)
- {
- c=idx(st[i]);
- u=ch[u][c];
- p=val[u]?
- u:last[u];
- while(p)
- {
- vis[val[p]]=true;
- //if(val[p]){ ans+=cnt[p]; cnt[p]=0; }
- flag=1;
- p=last[p];
- }
- }
- if(!flag) return false;
- //能够将出现的单词标号输出
- // for(i=1;i<=m;i++)
- // if(vis[i])
- // {
- // vis[i]=0;
- // printf(" %d",i);
- // }
- // puts("");
- return true;
- }
- } ac;
- int dp[1005][1005];
- void solve()
- {
- int i,j,k,len=strlen(txt+1);
- int id,next;
- memset(dp,0x3f,sizeof(dp));
- dp[0][0]=0;
- for(i=0;i<len;i++)
- {
- for(j=0;j<ac.sz;j++)
- {
- if(dp[i][j]>=INF) continue ;
- for(k=0;k<4;k++)
- {
- id=ac.idx(cc[k]);
- next=ac.ch[j][id];
- if(ac.have[next]) continue ;
- if(cc[k]==txt[i+1])
- {
- dp[i+1][next]=min(dp[i+1][next],dp[i][j]);
- }
- else
- {
- dp[i+1][next]=min(dp[i+1][next],dp[i][j]+1);
- }
- }
- }
- }
- ans=INF;
- for(j=0;j<ac.sz;j++) ans=min(ans,dp[len][j]);
- if(ans>=INF) ans=-1;
- }
- int main()
- {
- int i,j,n,ca=0;
- while(~scanf("%d",&n))
- {
- if(n==0) break ;
- ac.init();
- for(i=1;i<=n;i++)
- {
- scanf("%s",txt);
- ac.Insert(txt,i);
- }
- ac.build();
- scanf("%s",txt+1);
- solve();
- printf("Case %d: %d\n",++ca,ans);
- }
- return 0;
- }
poj 3691 DNA repair(AC自己主动机+dp)的更多相关文章
- POJ 2778 DNA Sequence (AC自己主动机 + dp)
DNA Sequence 题意:DNA的序列由ACTG四个字母组成,如今给定m个不可行的序列.问随机构成的长度为n的序列中.有多少种序列是可行的(仅仅要包括一个不可行序列便不可行).个数非常大.对10 ...
- Hdu 2457 DNA repair (ac自己主动机+dp)
题目大意: 改动文本串的上的字符,使之不出现上面出现的串.问最少改动多少个. 思路分析: dp[i][j]表示如今 i 个字符改变成了字典树上的 j 节点. 然后顺着自己主动机一直转移方程. 注意合法 ...
- POJ 3691 & HDU 2457 DNA repair (AC自己主动机,DP)
http://poj.org/problem?id=3691 http://acm.hdu.edu.cn/showproblem.php?pid=2457 DNA repair Time Limit: ...
- HDU 2457/POJ 3691 DNA repair AC自动机+DP
DNA repair Problem Description Biologists finally invent techniques of repairing DNA that contains ...
- POJ 3691 DNA repair(AC自动机+DP)
题目链接 能AC还是很开心的...此题没有POJ2778那么难,那个题还需要矩阵乘法,两个题有点相似的. 做题之前,把2778代码重新看了一下,回忆一下当时做题的思路,回忆AC自动机是干嘛的... 状 ...
- poj 1699 Best Sequence(AC自己主动机+如压力DP)
id=1699" target="_blank" style="">题目链接:poj 1699 Best Sequence 题目大意:给定N个D ...
- POJ 1625 Censored! (AC自己主动机 + 高精度 + DP)
题目链接:Censored! 解析:AC自己主动机 + 高精度 + 简单DP. 字符有可能会超过128.用map映射一下就可以. 中间的数太大.得上高精度. 用矩阵高速幂会超时,简单的DP就能解决时间 ...
- Hdu 3341 Lost's revenge (ac+自己主动机dp+hash)
标题效果: 举个很多种DNA弦,每个字符串值值至1.最后,一个长字符串.要安排你最后一次另一个字符串,使其没事子值和最大. IDEAS: 首先easy我们的想法是想搜索的!管她3721..直接一个字符 ...
- HDU - 2825 Wireless Password(AC自己主动机+DP)
Description Liyuan lives in a old apartment. One day, he suddenly found that there was a wireless ne ...
随机推荐
- Codeforces Round #247 (Div. 2) ABC
Codeforces Round #247 (Div. 2) http://codeforces.com/contest/431 代码均已投放:https://github.com/illuz/Wa ...
- How to make a combo box with fulltext search autocomplete support?
I would like a user to be able to type in the second or third word from a TComboBoxitem and for that ...
- Spring MVC概述
Spring MVC框架是一个开源的Java平台,为开发强大的基于Java的Web应用程序提供全面的基础架构支持非常容易和非常快速. Spring框架最初由Rod Johnson撰写,并于2003年6 ...
- appium+python自动化58-xpath定位
基本属性定位 以淘宝app为例,定位左上角扫一扫按钮 1.可以通过text文本定位到 //*[@text='text文本属性'] # 定位text driver.find_element_by_xpa ...
- python接口自动化9-https请求(SSL)
前言 本来最新的requests库V2.13.0是支持https请求的,但是一般写脚本时候,我们会用抓包工具fiddler,这时候会报:requests.exceptions.SSLError: [S ...
- 一次delete速度异常慢的处理过程
InnoDB delete from xxx速度暴慢原因 博客分类: database MySQLPythonMobile多线程SQL step1,一个简单的联系人表 CREATE TABLE `c ...
- Hive QL——深入浅出学Hive
第一部分:DDL DDL •建表 •删除表 •修改表结构 •创建/删除视图 •创建数据库 •显示命令 建表 CREATE [EXTERNAL] TABLE [IF NOT EXISTS] table_ ...
- iOS开源项目:FlatUIKit
FlatUIKit是iOS中具有扁平化风格的UI(Flat UI)组件.FlatUIKit的设计灵感来源于Flat UI和Kyle Miller.FlatUIKit中的组件是通过扩展(category ...
- 【Hibernate步步为营】--hql查询小介
HQL 是指Hibernate Query Language,它是Hibernate的查询语言,拥有一套自己的查询机制,它的查询语句和SQL非常类似.在使用的时候可以非常快上手.HQL提供了基本上SQ ...
- Reverse Integer--整数的反转
原题: Reverse digits of an integer. =>反转一个整数的数字.例子如下: Example1: x = 123, return 321 Example2: x = - ...