题目链接

题意:

  给n串有疾病的DNA序列,现有一串DNA序列,问最少修改几个DNA,能使新的DNA序列不含有疾病的DNA序列。

思路:

  构建AC自动机,设定end结点,dp[i][j]表示长度i的前缀串走到自动机的j点最少需要修改几个DNA。状态转移方程。那么只要转移到下一个的DNA不是end结点就能转移,如果下一个DNA不和原序列不一样就+1。

#include <bits/stdc++.h>

const int N = 50 + 5;
const int M = 1000 + 5;
const int INF = 0x3f3f3f3f;
struct AC {
static const int NODE = N * 20;
static const int SIZE = 4;
int ch[NODE][SIZE], fail[NODE], end[NODE];
int sz; void init();
int idx(char c);
void insert(char *s);
void get_fail();
}ac; char s[25];
char str[M];
int dp[M][AC::NODE]; int solve() {
int len = strlen (str);
memset (dp, INF, sizeof (dp));
dp[0][0] = 0; for (int i=1; i<=len; ++i) {
for (int j=0; j<ac.sz; ++j) {
if (dp[i-1][j] == INF) continue;
for (int k=0; k<4; ++k) {
if (!ac.end[ac.ch[j][k]]) {
dp[i][ac.ch[j][k]] = std::min (dp[i][ac.ch[j][k]], dp[i-1][j] + (ac.idx (str[i-1]) != k));
}
}
}
} int ret = INF;
for (int i=0; i<ac.sz; ++i) {
if (!ac.end[i]) {
ret = std::min (ret, dp[len][i]);
}
}
if (ret == INF) ret = -1;
return ret;
} int main() {
int n, cas = 0;
while (scanf ("%d", &n) == 1 && n) {
ac.init ();
for (int i=0; i<n; ++i) {
scanf ("%s", s);
ac.insert (s);
}
ac.get_fail ();
scanf ("%s", str); printf ("Case %d: %d\n", ++cas, solve ());
}
return 0;
} void AC::init() {
memset (ch[0], 0, sizeof (ch[0]));
sz = 1;
} int AC::idx(char c) {
if (c == 'A') {
return 0;
} else if (c == 'G') {
return 1;
} else if (c == 'C') {
return 2;
} else {
return 3;
}
} void AC::insert(char *s) {
int u = 0;
for (int c, i=0; s[i]; ++i) {
c = idx (s[i]);
if (!ch[u][c]) {
memset (ch[sz], 0, sizeof (ch[sz]));
end[sz] = 0;
ch[u][c] = sz++;
}
u = ch[u][c];
}
end[u] = 1;
} void AC::get_fail() {
fail[0] = 0;
std::queue<int> que;
for (int c=0; c<SIZE; ++c) {
int u = ch[0][c];
if (u) {
fail[u] = 0;
//last[u] = 0;
que.push (u);
}
}
while (!que.empty ()) {
int r = que.front ();
que.pop ();
for (int c=0; c<SIZE; ++c) {
int &u = ch[r][c];
if (!u) {
u = ch[fail[r]][c];
} else {
int v = fail[r];
while (v && !ch[v][c]) v = fail[v];
fail[u] = ch[v][c];
end[u] |= end[fail[u]];
//last[u] = end[fail[u]] ? fail[u] : last[fail[u]];
que.push (u);
}
}
}
}

  

最新文章

  1. #ifndef
  2. Spring声明式事务管理
  3. 使用 JavaScript 实现栈
  4. mm/kmalloc.c
  5. 【转】Linux 概念架构的理解
  6. Codeforces Round #100(140~~)
  7. 性能瞬间飙升!教你如何组RAID0磁盘阵列
  8. 关于找不到stdafx.h头文件问题
  9. UVA 10152-ShellSort(映射+栈)
  10. FileProvider解决FileUriExposedException
  11. [转载] Redis系统性介绍
  12. .netcore2.0+pgsql 脚手架
  13. C# System.Runtime.Caching使用
  14. HDU 3949 XOR [线性基|高斯消元]
  15. Centos 7 关闭selinux and firewall
  16. hive学习03-求一年中的最大温度
  17. SQL DCL 数据控制语句
  18. js try catch 的使用,容错处理
  19. 搭建基于crtmpserver的点播解决方案
  20. Python、Lua和Ruby比较——脚本语言大P.K.

热门文章

  1. maven配置远程仓库
  2. pic
  3. Qt - 错误总结 - 在自定义类头文件中添加Q_OBJECT 编译时报错(undefined reference to ‘vtable for xxThread)
  4. linux下查看和添加PATH环境变量
  5. rsa密钥文件转化为tortoise认可的pak密钥文件
  6. Django (2)
  7. 2015 史考特(Scottrade)开户指南 + 招商银行香港一卡通汇款【图文教程】
  8. java深入技术九 (注解)
  9. python 以及其他java php等在ubuntu上切换的命令
  10. mysql高并发和表类型