HDU 2457 DNA repair(AC自动机 + DP)题解
Posted kirinsb
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU 2457 DNA repair(AC自动机 + DP)题解相关的知识,希望对你有一定的参考价值。
题意:n个病毒串,给你一个串t,问你最少改几个能没有病毒串
思路:去年还觉得挺难得...其实就是AC自动机上跑一下简单的DP,每个位置都往没病毒的地方跑,然后看一下最少是什么。
代码:
#include<set> #include<map> #include<queue> #include<cmath> #include<string> #include<cstdio> #include<vector> #include<cstring> #include <iostream> #include<algorithm> using namespace std; typedef long long ll; typedef unsigned long long ull; const int maxn = 1000 + 5; const int M = 50 + 5; const ull seed = 131; const int INF = 0x3f3f3f3f; const int MOD = 20090717; int n, m; int dp[maxn][maxn]; int getid(char s) if(s == ‘A‘) return 0; if(s == ‘C‘) return 1; if(s == ‘G‘) return 2; return 3; struct Aho struct state int next[4]; int fail, cnt; node[maxn]; int size; queue<int> q; void init() size = 0; newtrie(); while(!q.empty()) q.pop(); int newtrie() memset(node[size].next, 0, sizeof(node[size].next)); node[size].cnt = node[size].fail = 0; return size++; void insert(char *s) int len = strlen(s); int now = 0; for(int i = 0; i < len; i++) int c = getid(s[i]); if(node[now].next[c] == 0) node[now].next[c] = newtrie(); now = node[now].next[c]; node[now].cnt = 1; void build() node[0].fail = -1; q.push(0); while(!q.empty()) int u = q.front(); q.pop(); if(node[node[u].fail].cnt && u) node[u].cnt = 1; for(int i = 0; i < 4; i++) if(!node[u].next[i]) if(u == 0) node[u].next[i] = 0; else node[u].next[i] = node[node[u].fail].next[i]; else if(u == 0) node[node[u].next[i]].fail = 0; else int v = node[u].fail; while(v != -1) if(node[v].next[i]) node[node[u].next[i]].fail = node[v].next[i]; break; v = node[v].fail; if(v == -1) node[node[u].next[i]].fail = 0; q.push(node[u].next[i]); void query(char *s) int len = strlen(s); for(int i = 0; i <= len; i++) for(int j = 0; j < size; j++) dp[i][j] = INF; dp[0][0] = 0; for(int i = 0; i < len; i++) for(int j = 0; j < size; j++) if(dp[i][j] == INF) continue; for(int k = 0; k < 4; k++) if(node[node[j].next[k]].cnt) continue; if(getid(s[i]) != k) dp[i + 1][node[j].next[k]] = min(dp[i + 1][node[j].next[k]], dp[i][j] + 1); else dp[i + 1][node[j].next[k]] = min(dp[i + 1][node[j].next[k]], dp[i][j]); int ans = INF; for(int i = 0; i < size; i++) if(node[i].cnt == 0) ans = min(ans, dp[len][i]); if(ans == INF) printf("-1\n"); else printf("%d\n", ans); ac; char s[1005]; int main() int ca = 1; while(~scanf("%d", &n) && n) ac.init(); for(int i = 0; i < n; i++) scanf("%s", s); ac.insert(s); ac.build(); scanf("%s", s); printf("Case %d: ", ca++); ac.query(s); 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)