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 ...
随机推荐
- Spring EL运算符实例
Spring EL支持大多数标准的数学,逻辑和关系运算符. 例如, 关系运算符 – 等于 (==, eq), 不等于 (!=, ne), 小于 (<, lt), 小于或等于 (<= , l ...
- .NET Transactional File Manager
.NET Transactional File Manager http://transactionalfilemgr.codeplex.com/ 对文件系统操作,比如copy, move, dele ...
- Silverlight:《Pro Silverlight5》读书笔记 之 Dependency Properties And Routed Event
Dependency Properties And Routed Event Dependency Properties Dynamic Value Resolution As you’ve alre ...
- [翻译] YLGIFImage 高效读取GIF图片
YLGIFImage 高效读取GIF图片 https://github.com/liyong03/YLGIFImage Asynchronized GIF image class and Image ...
- .a 库文件信息查看
在Linux 下经常需要链接一些 *.a的库文件,那怎么查看这些*.a 中包 含哪些文件.函数.变量: 1. 查看文件:ar -t *.a 2. 查看函数.变量:nm *.a
- iOS:搜索栏控件UISearchBar and SearchDisplayController的使用
UISearchBar and SearchDisplayController控件: 这是一个带搜索栏和搜索显示控制器的控件,前面的SearchBar是一个搜索栏,它提供一个输入搜索条件的类似于文本框 ...
- 彻底解决Odoo8.0单时区应用中的时区问题
原文地址:http://shine-it.net/index.php/topic,17001.0.html 由于数据库中存储的是UTC时区,默认情况下数据导出和group by都存在时区问题.彻底解决 ...
- 如何设置ESXi中的虚拟机随主机一同启动?
笔者新装了几台ESXi的主机, 其中一台上面运行着一台安装了vCenter的虚拟机. 笔者一路默认, 也没改什么设置. 在试图解决其他问题的过程中, 笔者重启了ESXi. 后来发现vCente登不进 ...
- JavaScript hash
location.hash -- 返回URL#后面的内容,如果没有#,返回空 hash,中文"哈希" 引用网址:http://www.dreamdu.com/javascript/ ...
- EChart处理三维数据做图表、多维legend图例处理
处理三维数据做图表,比如返回的数据就是一个个list,list里面某几个数据同属于一个维度,项目中的实例效果如下: 上面的khfx会有多个,比如db1.db2.db3等,下面的那些数据也会变化,目前需 ...