HDU 2457 DNA repair (AC自动机 + DP)
来源:互联网 发布:打车 数据 编辑:程序博客网 时间:2024/06/05 19:12
题目链接:DNA repair
解析:给出n个致病DNA序列,给一段DNA片段,问最少修改多少个碱基才能修复这段DNA序列中的所有致病序列。
AC自动机 + DP。
将n个致病DNA序列构成一个自动机。
令DP[i][j]表示长度为i走到节点j是所需改变的最少个数。
状态转移时,枚举下一步所有可能的碱基,然后判断该碱基是否达到匹配状态,若能,则安全转移,继续枚举下一个碱基;否则在不匹配的前提下,看该碱基加入之后是否跟上一状态相同,若不同,则需修复,即计数加一。若相同,直接转移即可。然后选择其中最小的修复个数即可。
AC代码:
#include <iostream>#include <cstdio>#include <queue>#include <cstring>using namespace std;const int INF = 0x3f3f3f3f;struct Trie{ int next[1010][4], fail[1010]; bool end[1010]; int root, L; int newnode(){ for(int i = 0; i < 4; i++) next[L][i] = -1; end[L++] = false; return L-1; } void init(){ L = 0; root = newnode(); } int getch(char ch){ if(ch == 'A') return 0; if(ch == 'C') return 1; if(ch == 'G') return 2; else return 3; } void insert(char s[]){ int len = strlen(s); int now = root; for(int i = 0; i < len; i++){ if(next[now][getch(s[i])] == -1) next[now][getch(s[i])] = newnode(); now = next[now][getch(s[i])]; } end[now] = true; } void build(){ queue<int> Q; for(int i = 0; i < 4; i ++){ if(next[root][i] == -1) next[root][i] = root; else{ fail[ next[root][i] ] = root; Q.push(next[root][i]); } } while(!Q.empty()){ int now = Q.front(); Q.pop(); if(end[ fail[now] ] == true) end[now] = true; //注意 for(int i = 0; i < 4; i ++){ if(next[now][i] == -1) next[now][i] = next[ fail[now] ][i]; else{ fail[ next[now][i] ] = next[ fail[now] ][i]; Q.push(next[now][i]); } } } } int dp[1010][1010]; int solve(char buf[]){ int len = strlen(buf); for(int i=0; i<=len; i++) for(int j=0; j<L; j++) dp[i][j] = INF; dp[0][root] = 0; for(int i=0; i<len; i++) for(int j=0; j<L; j++) if(dp[i][j] < INF){ for(int k=0; k<4; k++){ int newj = next[j][k]; if(end[newj]) continue; //可以安全转移 int tmp; if(k == getch(buf[i])) tmp = dp[i][j]; //相同,无需修复 else tmp = dp[i][j] + 1; //不同,修复次数加一 dp[i+1][newj] = min(dp[i+1][newj], tmp); } } int ans = INF; for(int i=0; i<L; i++) ans = min(ans, dp[len][i]); //选择最小的修复次数 if(ans == INF) ans = -1; return ans; }};Trie ac;char buf[1010];int main(){ #ifdef sxk freopen("in.txt", "r", stdin); #endif //sxk int n; int kase = 0; while(scanf("%d", &n) == 1 && n){ ac.init(); for(int i = 0; i < n; i ++){ scanf("%s", buf); ac.insert(buf); } ac.build(); scanf("%s", buf); printf("Case %d: %d\n", ++kase, ac.solve(buf)); } return 0;}
0 0
- hdu 2457 DNA repair(AC自动机+DP)
- HDU 2457 DNA repair(AC自动机+DP)
- 【HDU】2457 DNA repair AC自动机+DP
- hdu 2457 DNA repair ac自动机+dp
- Hdu 2457 DNA repair (ac自动机+dp)
- [AC自动机+dp] hdu 2457 DNA repair
- hdu 2457 DNA repair(AC自动机+DP)
- hdu 2457 DNA repair (ac自动机+dp)
- hdu 2457 DNA repair(ac自动机+dp)
- HDU 2457 DNA repair AC自动机+DP
- HDU - 2457 DNA repair AC自动机+dp
- Hdu 2457 DNA repair AC自动机+DP
- HDU 2457 DNA repair(AC自动机+DP)
- hdu DNA repair(AC自动机+DP)
- HDU 2457 DNA repair(AC自动机+DP)
- HDU 2457 DNA repair(AC自动机 + DP 入门)
- 字符串练习题: 【HDU 2457】 DNA repair(AC自动机+DP)
- HDU 2457 DNA repair (AC自动机 + DP)
- POJ 1141-Brackets Sequence(区间dp括号匹配打印路径)
- learn_python 函数
- 浅析Java数组声明、创建、初始化
- javascript object 相等判断逻辑
- Android spinner省市联动以及Xml解析
- HDU 2457 DNA repair (AC自动机 + DP)
- 分布式缓存
- USB之(四)HID设备类协议
- innobackupex参数之--incremental
- 从第m个数开始复制字符串
- output
- 操作系统一些概念
- [unity3d程序] 纹理扩散
- Fatal signal 11问题的解决方法