HDU2457 DNA repair —— AC自动机 + DP
题目链接:https://vjudge.net/problem/HDU-2457
DNA repair
Time Limit: 5000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 3126 Accepted Submission(s): 1661
You are to help the biologists to repair a DNA by changing least number of characters.
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.
number of characters which need to be changed. If it's impossible to repair the given DNA, print -1.
AAA
AAG
AAAG
2
A
TG
TGAATG
4
A
G
C
T
AGT
0
Case 2: 4
Case 3: -1
题意:
给出n个遗传病DNA序列,以及一个人体DNA序列,问至少修改多少个脱氧核苷酸,使得人体DNA序列不含遗传病?
题解:
1.将n个序列插入AC自动机。
2.设dp[i][j]为:处理到第i个字符,且当前状态为j(自动机上的状态)的最少修改数。
3.AC自动机实际上是一张有向图,如果要求字符串不含有自动机里面的病毒,那么字符串只能沿着自动机上的边走,当然需要去除病毒结点。所以状态转移:当字符串中的第i个字符与状态j的字符相同,那么dp[i+1][newj] = dp[i][j],否则dp[i+1][newj] = dp[i][j] + 1,dp[i+1][newj]取最小值即可。
代码如下:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <string>
#include <set>
using namespace std;
typedef long long LL;
const double EPS = 1e-;
const int INF = 2e9;
const LL LNF = 9e18;
const int MOD = 1e5;
const int MAXN = 1e3+; int Map[];
char M[];
int dp[MAXN][MAXN];
struct Trie
{
int sz, base;
int next[MAXN][], fail[MAXN], end[MAXN];
int root, L;
int newnode()
{
for(int i = ; i<sz; i++)
next[L][i] = -;
end[L++] = false;
return L-;
} void init(int _sz, int _base)
{
sz = _sz;
base = _base;
L = ;
root = newnode();
}
void insert(char buf[])
{
int len = strlen(buf);
int now = root;
for(int i = ; i<len; i++)
{
if(next[now][Map[buf[i]]] == -) next[now][Map[buf[i]]] = newnode();
now = next[now][Map[buf[i]]];
}
end[now] |= true;
}
void build()
{
queue<int>Q;
fail[root] = root;
for(int i = ; i<sz; i++)
{
if(next[root][i] == -) next[root][i] = root;
else fail[next[root][i]] = root, Q.push(next[root][i]);
}
while(!Q.empty())
{
int now = Q.front();
Q.pop();
end[now] |= end[fail[now]]; //当前串的后缀是否也包含单词
for(int i = ; i<sz; i++)
{
if(next[now][i] == -) next[now][i] = next[fail[now]][i];
else fail[next[now][i]] = next[fail[now]][i], Q.push(next[now][i]);
}
}
} int query(char s[])
{
int len = strlen(s);
for(int i = ; i<=len; i++)
for(int j = ; j<L; j++)
dp[i][j] = INF; dp[][] = ;
for(int i = ; i<len; i++)
for(int j = ; j<L; j++)
{
if(end[j] || dp[i][j]==INF) continue;
for(int k = ; k<sz; k++)
{
int newi = i+;
int newj = next[j][k];
if(end[newj]) continue;
dp[newi][newj] = min(dp[newi][newj], dp[i][j]+(s[i]!=M[k]));
}
} int ret = INF;
for(int i = ; i<L; i++)
ret = min(ret, dp[len][i]);
return ret==INF?-:ret;
}
}; Trie ac;
char buf[MAXN];
int main()
{
Map['A'] = ; Map['C'] = ; Map['G'] = ; Map['T'] = ; //离散化
M[] = 'A'; M[] = 'C'; M[] = 'G'; M[] = 'T';
int n, kase = ;
while(scanf("%d", &n) && n)
{
ac.init(,'A');
for(int i = ; i<=n; i++)
{
scanf("%s", buf);
ac.insert(buf);
}
ac.build();
scanf("%s", buf);
int ans = ac.query(buf);
printf("Case %d: %d\n", ++kase, ans);
}
return ;
}
HDU2457 DNA repair —— AC自动机 + DP的更多相关文章
- [hdu2457]DNA repair(AC自动机+dp)
题意:给出一些不合法的模式DNA串,给出一个原串,问最少需要修改多少个字符,使得原串中不包含非法串. 解题关键:多模式串匹配->AC自动机,求最优值->dp,注意在AC自动机上dp的套路. ...
- 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自动机是干嘛的... 状 ...
- POJ3691 DNA repair(AC自动机 DP)
给定N个长度不超过20的模式串,再给定一个长度为M的目标串S,求在目标串S上最少改变多少字符,可以使得它不包含任何的模式串 建立Trie图,求得每个节点是否是不可被包含的串,然后进行DP dp[i][ ...
- HDU 2457 DNA repair (AC自动机+DP)
题意:给N个串,一个大串,要求在最小的改变代价下,得到一个不含上述n个串的大串. 思路:dp,f[i][j]代表大串中第i位,AC自动机上第j位的最小代价. #include<algorithm ...
- hdu_2457_DNA repair(AC自动机+DP)
题目连接:hdu_2457_DNA repair 题意: 给你N个字符串,最后再给你一个要匹配的串,问你最少修改多少次,使得这个串不出现之前给的N的字符串 题解: 刚学AC自动机,切这题还真不知道怎么 ...
- poj 2778 DNA Sequence AC自动机DP 矩阵优化
DNA Sequence Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 11860 Accepted: 4527 Des ...
- POJ 2778 DNA Sequence (AC自动机+DP+矩阵)
题意:给定一些串,然后让你构造出一个长度为 m 的串,并且不包含以上串,问你有多少个. 析:很明显,如果 m 小的话 ,直接可以用DP来解决,但是 m 太大了,我们可以认为是在AC自动机图中,根据离散 ...
- HDU2457 DNA repair(AC自动机+DP)
题目一串DNA最少需要修改几个基因使其不包含一些致病DNA片段. 这道题应该是AC自动机+DP的入门题了,有POJ2778基础不难写出来. dp[i][j]表示原DNA前i位(在AC自动机上转移i步) ...
随机推荐
- Mockito 库、powermock扩展
转载:http://blog.csdn.net/kittyboy0001/article/details/18709685 Mockito 简介 Mockito 是目前 java 单测中使用比较流行的 ...
- > 1366 - Incorrect string value: '\xE6\xB5\x8B\xE8\xAF\x95...' for column 'description' at row 1 字符串格式错误
mysql 执行insert时报错 > 1366 - Incorrect string value: '\xE6\xB5\x8B\xE8\xAF\x95...' for column 'desc ...
- 关于rtsp转码rtmp播放的两种方式,客户端直接转,远程服务器转
需求 一.场景 用户多家门店有监控探头,设备是海康的和大华的.用户总部和门店不在一个网络下,并且总部要能实时调用查看门店监控,和门店回放画面.我们知道监控摄像机获取的视频是 rtsp 流的格式. 只能 ...
- 以前整理的网络上免费API接口
以前整理的一些免费的API接口,具体是否好用还需要时间测试,但是先分享给大家. 天气接口 聚合数据: http://op.juhe.cn/onebox/weather/query 用例 官方文档 来源 ...
- DevOps必备的20款顶级工具
原文地址:http://os.51cto.com/art/201606/512423.htm 开发运维工具与软件开发领域的最佳实践密切相关,也与必要的规范密切相关.在整个开发生命周期涉及到一大批新旧工 ...
- 关于iOS Tabbar的一些设置
事实上iOS Tabbar的可定制性很高,我们没有必要反复造轮子,以下是笔者收集的一些tabbar的经常使用设置.希望对大家有所帮助. 设置tabbar选中颜色 iOS7设置例如以下: [self.t ...
- 聊聊高并发(三十九)解析java.util.concurrent各个组件(十五) 理解ExecutorService接口的设计
上一篇讲了Executor接口的设计,目的是将任务的运行和任务的提交解耦.能够隐藏任务的运行策略.这篇说说ExecutorService接口.它扩展了Executor接口,对Executor的生命周期 ...
- C语言 结构体作为函数的参数
1)使用结构体变量作为函数的参数 使用结构体变量作为函数的实参时,采用的是值传递,会将结构体变量所占内存单元的内容全部顺序传递给形参,形参必须是同类型的结构体变量 demo: # include &l ...
- scrapy之Logging使用
#coding:utf-8 __author__ = 'similarface' ###################### ##Logging的使用 ###################### ...
- mac环境下清理系统垃圾clearMyMac 3.9 破解版
mac环境下清理系统垃圾clearMyMac 3 轻轻松松清理好几十G的垃圾文件 下载地址 链接: https://pan.baidu.com/s/1XZbZwzhgQCnzpvQDvyQrRA 密码 ...