HDU 2457 DNA repair(AC自动机 + DP 入门)
来源:互联网 发布:盛一伦非凡搭档知乎 编辑:程序博客网 时间:2024/06/14 07:02
题目链接:Click here~~
题意:
给 n 个带疾病的 DNA 串,然后给一个主串,问如何修改主串中最少个数的字符,使得主串中不包含带疾病的 DNA 串。
解题思路:
令 dp[i][j] 表示长度为 i,位于自动机中节点 j 的所需要修改的最少字符数。
每次转移时枚举下一个可能出现的字符,判断之后会到达的节点,只要不会包含带疾病的 DNA 串就可以进行转移。
#include <queue>#include <stdio.h>#include <string.h>#include <algorithm>using namespace std;#define CLR(a,v) memset(a,v,sizeof(a))namespace Trie{ const int N = 1005; const int Size = 4; int top; struct Node{ Node *next[Size], *f; //int ended_cnt; int ended_val; }node[N], *root; inline int get_id(char c) { if(c == 'A') return 0; if(c == 'G') return 1; if(c == 'C') return 2; if(c == 'T') return 3; return 5; } inline Node* new_node() { //node[top].ended_cnt = 0; node[top].ended_val = 0; CLR(node[top].next,NULL); return &node[top++]; } void init() { top = 0; root = new_node(); } void insert(char *s,int val=1) { Node *u = root; for(int i=0;s[i];i++) { int id = get_id(s[i]); if(u->next[id] == NULL) u->next[id] = new_node(); u = u->next[id]; } //u->ended_cnt++; u->ended_val = val; }}namespace ACam{ using namespace Trie; void get_fail() { queue<Node*> Q; for(int i=0;i<Size;i++) { Node *&ch = root->next[i]; if(!ch) ch = root; else { ch->f = root; Q.push(ch); } } while(!Q.empty()) { Node *cur = Q.front();Q.pop(); for(int i=0;i<Size;i++) { Node *&ch = cur->next[i]; if(!ch) ch = cur->f->next[i]; else { ch->f = cur->f->next[i]; ch->ended_val |= ch->f->ended_val; Q.push(ch); } } } } int dp[N][N]; int solve(char *s) { int n = strlen(s); memset(dp,63,sizeof(dp)); const int inf = dp[0][0]; dp[0][0] = 0; for(int i=0;i<n;i++) { for(int j=0;j<top;j++) { if(dp[i][j] == inf) continue; for(int k=0;k<Size;k++) { int jj = node[j].next[k] - node; if(node[jj].ended_val) continue; dp[i+1][jj] = min(dp[i+1][jj],dp[i][j] + (get_id(s[i]) != k ? 1 : 0)); } } } int ans = inf; for(int j=0;j<top;j++) ans = min(ans,dp[n][j]); return ans == inf ? -1 : ans; }}char str[1005];int main(){ int n, ncase = 0; while(~scanf("%d",&n),n) { ACam::init(); for(int i=0;i<n;i++) { scanf("%s",str); ACam::insert(str); } ACam::get_fail(); scanf("%s",str); int ans = ACam::solve(str); printf("Case %d: %d\n",++ncase,ans); } return 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
- 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)
- linux修改系统时间
- 两道概率题求解(半原创)
- 经典java代码找错题
- CSS3之渐变Gradient
- Spring事务配置的五种方式
- HDU 2457 DNA repair(AC自动机 + DP 入门)
- shopt nullglob, failglob, extglob, globstar用法
- uboot启动过程详解
- css3总结
- unity动态加载远程资源
- 邮件客户端
- 一次性输入多条记录
- 关于Linq
- 数组乘积--满足result[i] = input数组中除了input[i]之外所有数的乘积