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 ...
随机推荐
- [Win32]创建模态窗口
http://www.cnblogs.com/zplutor/archive/2011/02/20/1958973.html 在Win32编程中,如果要显示一个模态窗口,一般是先创建对话框模板,然后使 ...
- linux文件系统命令(6)---touch和mkdir
一.目的 本文将介绍linux下新建文件或文件夹.删除文件或文件夹命令. touch能够新建文件,mkdir用来新建文件夹.rm用来删除文件或文件夹. 本文将选取ubu ...
- 笔记本如何查看mac地址
最近有网友咨询他的笔记本如何查看mac地址,一般情况当我们需要用mac地址,ip地址,本地dns的时候都可以参考下面的方法 MAC地址又称为网卡的物理地址,每台电脑都有一个唯一的MAC地址,也正因 ...
- 两步改动CentOS主机名称
在CentOS系统中,改动主机名称的过程例如以下: 1. 改动network文件 编辑network文件.配置例如以下: vi /etc/sysconfig/network 配置 NETWORKING ...
- .NET:动态代理的 “5 + 1” 模式
背景 什么叫“动态代理”,代理模式我们都知道,动态代理就是动态生成的代理(采用Emit). 重量级的ORM和IOC产品离不开动态代理,作为开发人员,多数情况不用关注动态代理的内部实现机制,但是了解其一 ...
- getmask
#include "stdio.h" #include "stdlib.h" #include "string.h" #include &q ...
- Python任务调度模块 – APScheduler。动态修改调度时间间隔
APScheduler可以把调度任务放到内存里,也可以把任务放到数据库里,那么如何交互式修改定时任务的执行时间间隔或者下次执行时间呢? 方案一:把定时任务放到数据库里,修改数据库里任务的调度时间 方案 ...
- 【PAT】1024. Palindromic Number (25)
A number that will be the same when it is written forwards or backwards is known as a Palindromic Nu ...
- ArrayList的使用和List<T>的比较
使用非泛型集合类的限制可以通过编写一小段程序来演示,该程序利用 .NET Framework 基类库中的 ArrayList 集合类.ArrayList 是一个使用起来非常方便的集合类,无需进行修改即 ...
- powerdesigner 16.5 破解步骤
假设你的PowerDesigner已经安装完成.(PowerDesigner下载地址:http://pan.baidu.com/s/1mgqjmpa) 1. 从网上下载PowerDesigner165 ...