POJ 3691 DNA repair 基于AC自动机的DP
来源:互联网 发布:紫格尼克效应 知乎 编辑:程序博客网 时间:2024/06/05 16:08
dp[i][j] 表示长度为 i 的前缀到达第 j 个节点的最小更改数目。
很显然有dp[0][0] = 0;
dp[ i ][ j ] = min(dp[ i ][ j ],dp[i-1][k] + (j == k ? 0 : 1)),当且仅当j,k满足下列条件时。
j 不为某条模式串的末节点 且 j 到 root 的由失败指针组成的路径上无末节点。
j 是k的儿子节点 或者 j 的父节点可由 k 沿着失败指针找到。
#include <algorithm>#include <iostream>#include <cstring>#include <cstdlib>#include <cstdio>#include <queue>#include <cmath>#include <stack>#include <map>#pragma comment(linker, "/STACK:1024000000");#define EPS (1e-8)#define LL long long#define ULL unsigned long long#define _LL __int64#define INF 0x3f3f3f3fusing namespace std;const int MAXN = 4;struct N{ int next[MAXN],flag,fail;} st[1010];int Top;int sel(char c){ if(c == 'A') return 0; if(c == 'G') return 1; if(c == 'C') return 2; return 3;}int creat(){ memset(st[Top].next,-1,sizeof(st[Top].next)); st[Top].fail = -1,st[Top].flag = 0; return Top++;}int dp[1010][1010];char s[1010];void Get_Trie(int root,char *s){ int site = 1; while(s[site] != '\0') { if(st[root].next[sel(s[site])] == -1) st[root].next[sel(s[site])] = creat(); root = st[root].next[sel(s[site])]; ++site; } st[root].flag = 1;}int Get_Fail(int site,int tar){ while(site != -1 && st[site].next[tar] == -1) site = st[site].fail; if(site == -1) return 0; return st[site].next[tar];}queue<int> q;void Get_Fail(int root){ q.push(root); st[root].fail = -1; int f; while(q.empty() == false) { f = q.front(); q.pop(); for(int i = 0; i < MAXN; ++i) { if(st[f].next[i] != -1) { st[st[f].next[i]].fail = Get_Fail(st[f].fail,i); q.push(st[f].next[i]); } } }}bool Is_Safe(int site){ if(site == -1) return true; if(st[site].flag || Is_Safe(st[site].fail) == false) return false; return true;}int Is_Safe(int site,int tar){ if(site == -1) return 0; if(st[site].next[tar] != -1) { if(st[st[site].next[tar]].flag != 0 || Is_Safe(st[site].next[tar]) == false) return -1; return st[site].next[tar]; } return Is_Safe(st[site].fail,tar);}void Match(int root,char *s){ memset(dp,INF,sizeof(dp)); dp[0][0] = 0; int site,i,j,tmp; for(site = 1; s[site] != '\0'; ++site) { for(i = 0; i < Top; ++i) { if(dp[site-1][i] == INF) continue; for(j = 0; j < 4; ++j) { if(st[i].next[j] != -1 && st[st[i].next[j]].flag != 0) continue; if(st[i].next[j] != -1 && Is_Safe(st[i].next[j])) { dp[site][st[i].next[j]] = min(dp[site][st[i].next[j]],dp[site-1][i] + (j == sel(s[site]) ? 0 : 1)); continue; } tmp = Is_Safe(i,j); if(tmp == -1) continue; dp[site][tmp] = min(dp[site][tmp],dp[site-1][i] + (j == sel(s[site]) ? 0 : 1)); } } }}int main(){ int i,n; int icase = 1; int root; while(scanf("%d",&n) && n) { Top = 0; root = creat(); for(int i = 1; i <= n; ++i) { scanf("%s",s+1); Get_Trie(root,s); } Get_Fail(root); scanf("%s",s+1); Match(root,s); int anw = INF,len = strlen(s+1); for(i = 0; i < Top; ++i) anw = min(anw,dp[len][i]); printf("Case %d: %d\n",icase++,anw == INF ? -1 : anw); } return 0;}
0 0
- POJ 3691 DNA repair 基于AC自动机的DP
- POJ--3691[DNA repair] AC自动机+DP
- POJ 3691:DNA repair(AC自动机+DP)
- POJ 3691 DNA repair【AC自动机+DP】
- POJ 3691:DNA repair【AC自动机+DP】
- POJ 3691 DNA repair AC自动机DP
- poj 3691 DNA repair AC自动机+dp
- POJ 3691 DNA repair (AC自动机+dp)
- poj 3691 DNA repair(AC自动机+DP)
- POJ 3691 DNA repair (AC自动机 + dp)
- poj 3691 DNA repair AC自动机+DP
- POJ 3691 DNA repair AC自动机+DP -
- poj 3691 DNA repair AC自动机 dp
- POJ 3691 DNA repair AC自动机 + dp
- poj 3691 DNA repair 【ac自动机 + dp + spfa】
- Poj 3691 & Hdu 2457 DNA repair (AC自动机+DP)
- POJ 3691 & HDU 2457 DNA repair (AC自动机,DP)
- poj 3691 DNA repair(AC自动机+dp)
- 深入理解java虚拟机(二)HotSpot Java对象创建,内存布局以及访问方式
- 常见字符编码
- Linux 密码文件详解
- UVA - 10497 Sweet Child Makes Trouble
- Python中super关键字的作用
- POJ 3691 DNA repair 基于AC自动机的DP
- 带通配符的数
- LeetCode-Remove Duplicates from Sorted Array
- Python之美[从菜鸟到高手]--NotImplemented小析
- Codeforces Round #261 (Div. 2)
- 2015年华为提前招聘机试题--查找完数
- UVA - 297 Quadtrees
- 线性表之连续存储(数组)
- LeetCode 93 Restore IP Addresses