The main idea : give you n a the string of DNA, that is, to contain ' A ', ' T ', ' G ', ' C ' four bases, these given strings are inherited disease, and then give you a string of not more than 1000, ask you at least a few places to let this string does not contain hereditary disease, if no matter how modification is useless, output '-1 '
Analysis: Using Dp[ni][nnode], indicating the length of the time I reached the nth node modification of the minimum number of times, and then the last level to count the minimum number of rows.
The code is as follows:
=============================================================================================================== ==============
#include <iostream>#include<algorithm>#include<stdio.h>#include<string.h>#include<queue>using namespacestd;Const intMAXN =1007;Const intMAXM = $;Const intMaxson =4;Const intOO = 1e9+7;intDP[MAXN][MAXN];structac_trie{intNext[maxn][maxson]; intFAIL[MAXN], END[MAXN]; intcnt, Root; intNewNode () { for(intI=0; i<maxson; i++) Next[cnt][i]= -1; FAIL[CNT]= end[cnt] =false; returncnt++; } voidInIt () {CNT=0; Root=NewNode (); } intFind (Charch) { if(ch = ='A')return 0; if(ch = ='T')return 1; if(ch = ='G')return 2; return 3; } voidInsert (Chars[]) { intnow =Root; for(intI=0; T[n]; i++) { intK =Find (S[i]); if(Next[now][k] = =-1) Next[now][k]=NewNode (); now=Next[now][k]; } End[now]=true; } voidgetfial () {Queue<int>p; intnow =Root; for(intI=0; i<maxson; i++) { if(Next[now][i] = =-1) Next[now][i]=Root; Else{Fail[next[now][i]]=Root; Q.push (Next[now][i]); } } while(Q.size ()) { now=Q.front (); Q.pop (); for(intI=0; i<maxson; i++) { if(Next[now][i] = =-1) Next[now][i]=Next[fail[now]][i]; Else{Fail[next[now][i]]=Next[fail[now]][i]; Q.push (Next[now][i]); }} End[now]|=End[fail[now]]; } }}; Ac_trie AC;intMain () {intN, t=1; while(SCANF ("%d", &N), N) {CharS[MAXN]; Ac. InIt (); for(intI=0; i<n; i++) {scanf ("%s", s); Ac. Insert (s); } AC. Getfial (); scanf ("%s", s+1); N=strlen (s); for(intI=0; i<=n; i++) for(intj=0; j<ac.cnt; J + +) Dp[i][j]=Oo; dp[0][0] =0; for(intI=0; i<n-1; i++) for(intj=0; j<ac.cnt; J + +) for(intk=0; k<4; k++) { intW =Dp[i][j]; intNext =Ac.next[j][k]; if(AC. End[next])Continue; if(AC. Find (s[i+1]) !=k) W++; if(dp[i+1][next] >W) dp[i+1][next] =W; } intMin =Oo; for(intI=0; i<ac.cnt; i++) Min= min (min, dp[n-1][i]); if(Min = =oo) Min= -1; printf ("Case %d:%d\n", t++, Min); } return 0;}
DNA repair-hdu 2457 (Automaton +DP)