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());
}
}
相關文章
- poj--2778DNA Sequence+AC自動機+矩陣快速冪矩陣
- poj--1625Censored!+AC自動機上的dp+大數
- [複習] AC自動機
- AC自動機 提高篇
- 簡單版AC自動機
- AC自動機:Tire樹+KMPKMP
- AC 自動機——多模式串匹配模式
- 專題十七 AC自動機【Kuangbin】
- AC自動機學習筆記筆記
- AC 自動機學習筆記筆記
- 從零開始發明 AC 自動機
- AC自動機+字典序+樹狀陣列陣列
- POJ 3071 Football(概率DP)
- POJ 3267 The Cow Lexicon(dp)
- hdu2222--Keywords Search+AC自動機模板
- Aho-Corasick 演算法 AC自動機實現演算法
- hdu-5384Danganronpa+多校訓練+AC自動機
- 簡單dp -- Common Subsequence POJ - 1458
- POJ1390 Blocks (區間DP)BloC
- AC自動機+trie樹實現高效多模式匹配字典模式
- POJ3252Round Numbers(數位dp)
- Making the Grade POJ - 3666(離散化+dp)
- hdu 1277 AC自動機入門(指標版和陣列版)指標陣列
- 「暑期訓練」「基礎DP」 Common Subsequence (POJ-1458)
- 「畢昇一號」DNA活字儲存噴墨印表機來了,低成本、高效率、全自動的DNA儲存
- 讓DNA說Hello!微軟成功研製用DNA儲存讀取資料的全自動系統微軟
- HanLP — Aho-Corasick DoubleArrayTire 演算法 ACDAT - 基於雙陣列字典樹的AC自動機HanLP演算法陣列
- 自研AC配置(上電過程)
- 機率DP
- 動態 DP
- ac79啟動流程
- 自動機
- USACO 1.4 Barn Repair 修理牛棚 (動態規劃)AI動態規劃
- 自研AP配置(上電發現AC)
- KMP 自動機KMP
- BOSHIDA AC/DC電源模組:應用於工業自動化領域
- 傑裡之AC696N 的藍芽連線成功自動播放【篇】藍芽
- DP動態規劃-爬塔(雙層dp)動態規劃
- MogDB備機處於standby need-repair(WAL)狀態AI