標籤:else 部分 uil out ase tput 產生 序列 res
題意:
生物課上我們學到,DNA序列中只有A, C, T和G四種片段。
經科學發現,DNA序列中,包含某些片段會產生不好的基因,如片段”ATC”是不好片段,則”AGATCC”, “CATCAA”, “ATCATC”都是不好的DNA序列,這些不好片段我們可以稱為病毒片段。
現在已知m個病毒片段, 然後給定一個DNA串,問如果使用最少的修改(將DNA中的某個字母,變為其他字母,比如A變T,但變的字母也只能是”ACTG”),使得這個DNA串不包含病毒片段。
【資料規模和約定】
1<=m<=50 病毒片段長度不超過20,只含A,T,C,G字母
DNA串長度不超過1000, 只含A, T, C, G字母
思路:AC自動機上的DP
判斷是否病毒部分與上一道相同
設dp[i,j]為在原串上前i個字母上改,現在在自動機上j號節點的最小值
\[ dp[i,x]=min\begin{cases} dp[i-1,j] (k=ch[i])\\dp[i-1,j]+1 (k<>ch[i])\end{cases} \]
其中x為j號節點走字母k之後所到達的節點號,要求j號節點為合法節點
答案即為\[ min(dp[len,i]) (i為合法節點) \]
1 const s:array[1..4]of char=(‘A‘,‘C‘,‘G‘,‘T‘); 2 oo=500000000; 3 var map:array[1..1100,‘A‘..‘T‘]of longint; 4 dp:array[0..1100,0..1000]of longint; 5 b,f:array[0..1100]of longint; 6 q:array[1..200000]of longint; 7 n,tot,i,j,k,d,ans,num,p,cas:longint; 8 ch:ansistring; 9 10 11 procedure build;12 var i,d,u:longint;13 begin14 u:=1; d:=length(ch);15 for i:=1 to d do16 begin17 if map[u,ch[i]]=0 then begin inc(num); map[u,ch[i]]:=num; end;18 u:=map[u,ch[i]];19 end;20 b[u]:=1;21 end;22 23 procedure acauto;24 var t,w,u,p,son,i:longint;25 begin26 t:=0; w:=1; q[1]:=1;27 while t<w do28 begin29 inc(t); u:=q[t];30 if b[f[u]]=1 then b[u]:=1;31 for i:=1 to 4 do32 if map[u,s[i]]>0 then33 begin34 son:=map[u,s[i]];35 p:=f[u];36 if u=1 then f[son]:=137 else f[son]:=map[p,s[i]];38 inc(w); q[w]:=son;39 end40 else41 begin42 p:=f[u];43 if u=1 then map[u,s[i]]:=144 else map[u,s[i]]:=map[p,s[i]];45 end;46 end;47 end;48 49 function min(x,y:longint):longint;50 begin51 if x<y then exit(x);52 exit(y);53 end;54 55 begin56 assign(input,‘poj3691.in‘); reset(input);57 assign(output,‘poj3691.out‘); rewrite(output);58 while not eof do59 begin60 fillchar(f,sizeof(f),0);61 fillchar(b,sizeof(b),0);62 fillchar(dp,sizeof(dp),$1f);63 for i:=1 to num do64 for j:=1 to 4 do map[i,s[j]]:=0;65 readln(n);66 if n=0 then break;67 num:=1; inc(cas);68 for i:=1 to n do69 begin70 readln(ch);71 build;72 end;73 acauto;74 readln(ch);75 dp[0,1]:=0; d:=length(ch);76 for i:=1 to d do77 for j:=1 to num do78 if (b[j]=0)and(dp[i-1,j]<oo) then79 for k:=1 to 4 do80 begin81 p:=map[j,s[k]];82 if b[p]=0 then83 begin84 if ch[i]=s[k] then dp[i,p]:=min(dp[i,p],dp[i-1,j])85 else dp[i,p]:=min(dp[i,p],dp[i-1,j]+1);86 end;87 end;88 ans:=oo;89 for i:=1 to num do90 if b[i]=0 then ans:=min(ans,dp[d,i]);91 write(‘Case ‘,cas,‘: ‘);92 if ans<oo then writeln(ans)93 else writeln(-1);94 end;95 close(input);96 close(output);97 end.
【POJ3691】DNA repair(AC自動機,DP)