Question:
Give n words, and then a string of STR (containing only A, G, C, and T)
Question: How many characters can be modified for STR without containing N words?
Ideas:
Create a trie graph and create an automatic DP
DP [I] [J] indicates that at least a few characters must be modified on the J node for I letters that pass through Str.
Trie*P=Node[J]->Next[K]; If (P->Mark) Continue; // inaccessibleDP[I] [P->ID] =Min(DP[I] [P->ID],DP[I-1] [J] + (GETID(Fuck[I])! =K));
That is, step I goes from node J to the corresponding K. If K is not the letter in this step, modify it and take the minimum value.
When the traversal length is Len, the minimum value is used.
Code:
#include"cstdlib"#include"cstdio"#include"cstring"#include"cmath"#include"queue"#include"algorithm"#include"iostream"#include"map"#include"string"#define inf 9999999using namespace std;int triecont;struct trie{ int mark,id; trie *next[5],*fail; trie() { memset(next,0,sizeof(next)); fail=NULL; mark=id=0; }};trie *root,*node[1234];int getid(char x){ if(x=='A') return 0; else if(x=='C') return 1; else if(x=='G') return 2; return 3;}void init(char *v){ trie *p=root; for(int i=0;v[i];i++) { int tep=getid(v[i]); if(p->next[tep]==NULL) { p->next[tep]=new trie(); node[triecont]=p->next[tep]; p->next[tep]->id=triecont++; } p=p->next[tep]; } p->mark=1;}void getac(){ queue<trie*>q; q.push(root); while(!q.empty()) { trie *p=q.front(); q.pop(); for(int i=0;i<4;i++) { if(p->next[i]==NULL) { if(p==root) p->next[i]=root; else p->next[i]=p->fail->next[i]; } else { if(p==root) p->next[i]->fail=root; else p->next[i]->fail=p->fail->next[i]; q.push(p->next[i]); trie *tep=p; while(tep!=root && tep->mark!=1) tep=tep->fail; p->mark=tep->mark; } } }}int dp[1234][1234];char fuck[1234];int main(){ int n; int cas=1; while(scanf("%d",&n),n) { triecont=0; root=new trie(); node[triecont]=root; root->id=triecont++; while(n--) { char x[33]; scanf("%s",x); init(x); } getac(); //for(int i=0;i<triecont;i++) printf("%d:%d\n",i,node[i]->mark); scanf("%s",fuck+1); int len=strlen(fuck+1); for(int i=0;i<=len;i++) for(int j=0;j<triecont;j++) dp[i][j]=inf; dp[0][0]=0; for(int i=1;i<=len;i++) { for(int j=0;j<triecont;j++) { if(dp[i-1][j]==inf) continue; for(int k=0;k<4;k++) { trie *p=node[j]->next[k]; if(p->mark) continue; dp[i][p->id]=min(dp[i][p->id],dp[i-1][j]+(getid(fuck[i])!=k)); } } } int ans=inf; for(int i=0;i<triecont;i++) ans=min(ans,dp[len][i]); printf("Case %d: %d\n",cas++,ans==inf?-1:ans); } return 0;}
[AC + dp] HDU 2457 DNA Repair