POJ 3691 DNA repair (AC自動機 + dp)
Time Limit: 2000MS | Memory Limit: 65536K | |
Total Submissions: 6014 | Accepted: 2820 |
Description
Biologists finally invent techniques of repairing DNA that contains segments causing kinds of inherited diseases. For the sake of simplicity, a DNA is represented as a string containing characters 'A', 'G' , 'C' and 'T'. The repairing techniques are simply to change some characters to eliminate all segments causing diseases. For example, we can repair a DNA "AAGCAG" to "AGGCAC" to eliminate the initial causing disease segments "AAG", "AGC" and "CAG" by changing two characters. Note that the repaired DNA can still contain only characters 'A', 'G', 'C' and 'T'.
You are to help the biologists to repair a DNA by changing least number of characters.
Input
The following N lines gives N non-empty strings of length not greater than 20 containing only characters in "AGCT", which are the DNA segments causing inherited disease.
The last line of the test case is a non-empty string of length not greater than 1000 containing only characters in "AGCT", which is the DNA to be repaired.
The last test case is followed by a line containing one zeros.
Output
number of characters which need to be changed. If it's impossible to repair the given DNA, print -1.
Sample Input
2 AAA AAG AAAG 2 A TG TGAATG 4 A G C T AGT 0
Sample Output
Case 1: 1 Case 2: 4 Case 3: -1
Source
2008 Asia Hefei Regional Contest Online by USTC
題目連結:http://poj.org/problem?id=3691
題目大意:給一些壞的字串,要求主串中不出現壞的字串,問最少要改變幾個主串中的字元
題目分析:將問題變為在 AC機上走(不走過危險結點),使得走過的路徑得到的串與目標串匹配最多,建AC機的時候如果一個點失敗指標指的點是壞點,那它也是壞點,相當於這個壞字串是另一個的子串,這裡還需要用Trie圖優化,方便dp時候狀態的轉移,dp[i][j]表示主串匹配了前i個字元且自動機在j結點時最少要改變的字元數,注意dp的時候要避開壞點
#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
using namespace std;
int const MAX = 1005;
int const INF = 1 << 30;
char s[50], t[MAX];
struct AC_DP
{
int tot, root, fail[MAX], next[MAX][4];
int dp[MAX][MAX];
bool bad[MAX];
inline int chg(char ch)
{
if(ch == 'A')
return 0;
if(ch == 'T')
return 1;
if(ch == 'C')
return 2;
return 3;
}
inline int Newnode()
{
for(int i = 0; i < 4; i++)
next[tot][i] = -1;
fail[tot] = 0;
bad[tot] = false;
return tot ++;
}
inline void Init()
{
tot = 0;
root = Newnode();
}
inline void Insert(char *s)
{
int len = strlen(s);
int p = root;
for(int i = 0; i < len; i++)
{
int idx = chg(s[i]);
if(next[p][idx] == -1)
next[p][idx] = Newnode();
p = next[p][idx];
}
bad[p] = true;
}
inline void Build()
{
queue <int> q;
q.push(root);
while(!q.empty())
{
int p = q.front();
q.pop();
for(int i = 0; i < 4; i++)
{
if(next[p][i] == -1)
{
if(p == root)
next[p][i] = root;
else
next[p][i] = next[fail[p]][i];
}
else
{
if(p == root)
fail[next[p][i]] = root;
else
{
fail[next[p][i]] = next[fail[p]][i];
bad[p] |= bad[fail[p]];
}
q.push(next[p][i]);
}
}
}
}
inline int DP()
{
int tlen = strlen(t);
int ans = INF;
for(int i = 0; i <= tlen; i++)
for(int j = 0; j < tot; j++)
dp[i][j] = INF;
dp[0][0] = 0;
for(int i = 1; i <= tlen; i++)
for(int j = 0; j < tot; j++)
if(dp[i - 1][j] < INF)
for(int k = 0; k < 4; k++)
if(!bad[next[j][k]])
dp[i][next[j][k]] = min(dp[i][next[j][k]], dp[i - 1][j] + (chg(t[i - 1]) != k));
for(int j = 0; j < tot; j++)
if(!bad[j])
ans = min(ans, dp[tlen][j]);
if(ans == INF)
return -1;
return ans;
}
}ac;
int main()
{
int n, ca = 1;
while(scanf("%d", &n) != EOF && n)
{
ac.Init();
for(int i = 0; i < n; i++)
{
scanf("%s", s);
ac.Insert(s);
}
scanf("%s", t);
ac.Build();
printf("Case %d: %d\n", ca ++, ac.DP());
}
}
相關文章
- 【Ac自動機+矩陣加速】poj 2778 DNA Sequence矩陣
- poj--2778DNA Sequence+AC自動機+矩陣快速冪矩陣
- POJ 2778-DNA Sequence(AC自動機+構建鄰接矩陣+矩陣快速冪)矩陣
- poj 2778 AC自動機與矩陣連乘矩陣
- AC自動機:Tire樹+KMPKMP
- AC 自動機——多模式串匹配模式
- AC自動機學習筆記筆記
- 【Ac自動機】hdu 5880 Family ViewView
- BZOJ 1030: [JSOI2007]文字生成器 DP,AC自動機JS
- 從零開始發明 AC 自動機
- bzoj1030: [JSOI2007]文字生成器(AC自動機+Dp)JS
- Aho-Corasick 演算法 AC自動機實現演算法
- hdu2243 ac自動機+矩陣連乘矩陣
- POJ 3253 Fence Repair 優先佇列AI佇列
- AC自動機+trie樹實現高效多模式匹配字典模式
- POJ1745Divisibility(dp)
- POJ2955 Brackets (區間DP)Racket
- POJ 2486 Apple Tree(樹形dp)APP
- POJ 1925 Spiderman(線性dp)IDE
- POJ 3744 概率dp+矩陣矩陣
- POJ 3253Fence Repair(哈夫曼&優先佇列)AI佇列
- hdu 1277 AC自動機入門(指標版和陣列版)指標陣列
- POJ1160 Post Office[序列DP]
- 【dp】POJ 1015 Jury CompromisePromise
- POJ 3249-Test for Job(拓撲排序&&DP)排序
- POJ 3107 Godfather(樹形dp)Go
- POJ 3017 單調佇列dp佇列
- 【樹形dp】poj 1947 Rebuilding RoadsRebuild
- poj 1180 dp的斜率優化優化
- POJ 1664 放蘋果 (基礎組合dp)蘋果
- POJ 2955-Brackets(括號匹配-區間DP)Racket
- hdu2896 AC自動機-標記哪些模式串在目標串中出現過模式
- 讓DNA說Hello!微軟成功研製用DNA儲存讀取資料的全自動系統微軟
- 【Ac自動機 查詢是否存在一個字典中的字串】hihocoder 1036 Trie圖字串
- hdu2222 AC自動機-給定串中出現了幾個模式串模式
- POJ 1276-Cash Machine(多重部分和-dp)Mac
- poj3017 dp+單調佇列佇列
- POJ 3253-Fence Repair(哈夫曼樹-最小值優先佇列)AI佇列