题意 就是将一个含有 病毒的字符串 修改成一个不含病毒的字符串;
方法 由于 只有 四种字符,那么状态就很少了,每步只有四个状态可达,上一个状态只有 1000多种,所以能承受;
#include<iostream> #include<stdio.h> #include<cstring> #include<algorithm> using namespace std; struct date { date *next[5],*fail; int in,flag; }tree[1123],*que[1123],*root; int total,head,tail,hash[556]; char str[1004]; date *creat_node( ) { for( int i = 0; i <= 4; i++ ) tree[total].next[i] = NULL; tree[total].fail = NULL; tree[total].in = total; tree[total].flag = false; return &tree[total++]; } void inint( ) { hash[int('A')] = 1; hash[int('C')] = 2; hash[int('G')] = 3; hash[int('T')] = 4; head = tail = total = 0; root = creat_node(); root->fail = root; } void insert( char *word ) { date *temp = root; while( *word ) { int num = hash[int(*word)]; if( temp->next[num] == NULL ) temp->next[num] = creat_node(); temp = temp->next[num]; word++; } temp->flag = true; } void build_AC( ) { que[tail++] = root; while( tail > head ) { date *temp = que[head++]; for( int i = 1; i <= 4; i++ ) if( temp->next[i] != NULL ) { if( temp == root ) temp->next[i]->fail = root; else temp->next[i]->fail = temp->fail->next[i]; temp->next[i]->flag = (temp->next[i]->flag | temp->next[i]->fail->flag)|temp->flag; que[tail++] = temp->next[i]; } else { if( temp == root )temp->next[i] = root; else temp->next[i] = temp->fail->next[i]; } } } int dp[1123][1123]; void DP( ) { int i,j,k,len = strlen( str ); for( i = 0; i <= 1120; i++ ) for( j = 0; j <= 1120; j++ ) dp[i][j] = 199999999; dp[0][0] = 0; for( i = 1; i <= len ; i++ ) for( j = 0; j < total; j++ ) for( k = 1; k <= 4; k++ ) if( !tree[j].next[k]->flag ) { if( hash[int(str[i-1])] == k ) dp[i][tree[j].next[k]->in] = min( dp[i][tree[j].next[k]->in],dp[i-1][j] ); else dp[i][tree[j].next[k]->in] = min( dp[i][tree[j].next[k]->in],dp[i-1][j] + 1 ); } int res = 199999999; for( i = 0; i < total; i++ ) if( tree[i].flag == false ) res = min( res,dp[len][i] ); if( res == 199999999 ) printf("-1\n"); else printf("%d\n",res); } int main( ) { int N,i,k = 1; while( scanf("%d",&N) && N ) { inint( ); for( i = 1; i <= N; i++ ) scanf("%s",&str),insert( str ); build_AC( ); scanf("%s",&str); printf("Case %d: ",k++); DP( ); } }