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 2 Sample Output Case 1: 1 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 ... 
随机推荐
- Cascode MOSFET increases boost regulator's input- and output-voltage ranges
			Targeting use in portable-system applications that require raising a battery's voltage to a higher l ... 
- 在安卓上,微信公众号无法分享到QQ的解决办法之一
			今天做一个微信公众号分享功能,参考微信sdk,代码几乎没有任何问题,但就是分享到QQ失败,以下是我QQ分享部分的代码: wx.onMenuShareQQ({ title: '快来和我一起玩转大脑', ... 
- 把Jar文件转成exe安装文件
			1.你要清楚的目标文件是32位还是64位的,如果生成的是32位,你就要使用32位的jre,如果生成的是64位,就要使用64位的jre. 图 1 在圆圈位置进行32bit或64bit的选择.因为我要创建 ... 
- 描述 Machine.Config 和 Web.Config(转载)
			NET Framework 提供的配置管理包括范围广泛的设置,允许管理员管理 Web 应用程序及其环境.这些设置存储在 XML 配置文件中,其中一些控制计算机范围的设置,另一些控制应用程序特定的配置. ... 
- iOS中WebKit框架应用与解析
			WebKit是iOS8之后引入的专门负责处理网页视图的框架,其比UIWebView更加强大,性能也更优. 引言 在iOS8之前,在应用中嵌入网页通常需要使用UIWebView这样一个类,这个类通过UR ... 
- zedboard--基于zedboard的demo系统的boa服务器搭建(二十一)
			zedboard提供的demo系统很迷你,但是也能移植嵌入式Web服务器的.这里就移植boa服务器. 1.下载Boa服务器源代码(安装好了交叉编译器) http://www.boa.org/,选择最后 ... 
- 通过form表单上传文件获取后台传来的数据
			小伙伴是不是遇到过这样的问题,通过submit提交form表单的时候,不知怎么获取后台传来的返回值.有的小伙伴就会说你不会发送ajax,其实也会.假如提交的form表单中含有文件,怎么办? 步骤1:想 ... 
- Sqlite-SQLiteHelper类,操作SQLite数据库
			using System; using System.Data; using System.Text.RegularExpressions; using System.Xml; using Syste ... 
- 步步为营_Android开发课[3]_Activity学习
			Focus on technology, enjoy life! -- QQ:804212028 浏览链接:http://blog.csdn.net/y18334702058/article/deta ... 
- TCP/IP具体解释学习笔记——地址解析协议ARP
			一 概述 我们知道,IP协议是用来在不同的物理网络之间数据传输的.要在不同的网络之间数据传输,至少须要将IP协议所用的地址转换成特定网络所使用的物理地址. 一般来说.就是将IPv4地址转换为mac地址 ... 
