从开始节点往下走,不能走到病毒节点,如果当前状态与原始串不一样就+1,取一个最小值.
1 #include <iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<stdlib.h> 6 #include<vector> 7 #include<cmath> 8 #include<queue> 9 #include<set> 10 #include<string> 11 using namespace std; 12 #define N 1005 13 #define LL long long 14 #define INF 0xfffffff 15 const double eps = 1e-8; 16 const double pi = acos(-1.0); 17 const double inf = ~0u>>2; 18 const int child_num = 4; 19 char vir[25]; 20 char s[N]; 21 class AC 22 { 23 private: 24 int ch[N][child_num]; 25 int fail[N]; 26 int Q[N]; 27 int val[N]; 28 int sz; 29 int id[128]; 30 char po[5]; 31 int dp[N][N]; 32 public: 33 void init() 34 { 35 fail[0] = 0; 36 id['A'] = 0,id['G'] = 1,id['T'] = 2,id['C'] = 3; 37 po[0] = 'A',po[1] = 'G',po[2] = 'T',po[3] = 'C'; 38 } 39 void reset() 40 { 41 memset(ch[0],0,sizeof(ch[0])); 42 memset(val,0,sizeof(val)); 43 sz = 1; 44 } 45 void insert(char *a,int key) 46 { 47 int p = 0; 48 for(; *a ; a++) 49 { 50 int d= id[*a]; 51 if(ch[p][d]==0) 52 { 53 memset(ch[sz],0,sizeof(ch[sz])); 54 s[sz] = *a; 55 ch[p][d] = sz++; 56 } 57 p = ch[p][d]; 58 } 59 val[p] = (1<<key); 60 } 61 void construct() 62 { 63 int i,head=0,tail = 0; 64 for(i = 0; i < child_num ;i++) 65 { 66 if(ch[0][i]) 67 { 68 fail[ch[0][i]] = 0; 69 Q[tail++] = ch[0][i]; 70 } 71 } 72 while(head!=tail) 73 { 74 int u = Q[head++]; 75 val[u]|=val[fail[u]]; 76 for(i = 0; i < child_num ; i++) 77 { 78 if(ch[u][i]) 79 { 80 fail[ch[u][i]] = ch[fail[u]][i]; 81 Q[tail++] = ch[u][i]; 82 } 83 else ch[u][i] = ch[fail[u]][i]; 84 } 85 } 86 } 87 void work(int n,int kk) 88 { 89 int i,j,g; 90 for(i = 0 ; i <= n ;i++) 91 for(j = 0 ;j <= sz ; j++) 92 dp[i][j] = INF; 93 dp[0][0] = 0; 94 for(i = 0 ; i < n ;i++) 95 { 96 for(j = 0 ;j < sz; j++) 97 { 98 for(g = 0 ;g < child_num ; g++) 99 { 100 if(val[ch[j][g]]) continue; 101 int o = 0; 102 if(po[g]!=s[i]) o = 1; 103 dp[i+1][ch[j][g]] = min(dp[i+1][ch[j][g]],dp[i][j]+o); 104 } 105 } 106 } 107 int ans = INF; 108 for(i = 0 ;i < sz ; i++) 109 ans = min(ans,dp[n][i]); 110 printf("Case %d: ",kk); 111 if(ans==INF) 112 puts("-1"); 113 else 114 printf("%d ",ans); 115 } 116 }ac; 117 int main() 118 { 119 int i,m,kk=0; 120 ac.init(); 121 while(scanf("%d",&m)&&m) 122 { 123 ac.reset(); 124 for(i = 1;i <= m ;i++) 125 { 126 scanf("%s",vir); 127 ac.insert(vir,1); 128 } 129 ac.construct(); 130 scanf("%s",s); 131 int k = strlen(s); 132 ac.work(k,++kk); 133 } 134 return 0; 135 }