#include<bits/stdc++.h>
using namespace std;#definedbdouble#definelllonglong#definePirpair<int,int>#definefifirst#definesesecond#definepbpush_back#definem_pmake_pair#defineinf0x3f3f3f3f#defineINF0x3f3f3f3f3f3f3f3f/*==========ACMer===========*/constint N =1005;int n;char s[N];int tr[N][4], fa[N], mk[N], idx;int dp[N][N];int id[150];voidpre_do(){
id['A']=0;
id['G']=1;
id['C']=2;
id['T']=3;}voidinsert(){int u =0;for(int i =0; s[i]; i ++){if(tr[u][id[s[i]]]==0) tr[u][id[s[i]]]=++ idx;
u = tr[u][id[s[i]]];}
mk[u]=1;}voidbuild(){
queue<int> q;for(int i =0; i <4; i ++){if(tr[0][i]) q.push(tr[0][i]);}while(q.size()){int u = q.front(); q.pop();if(mk[fa[u]]) mk[u]=1;for(int i =0; i <4; i ++){if(tr[u][i])
fa[tr[u][i]]= tr[fa[u]][i], q.push(tr[u][i]);else
tr[u][i]= tr[fa[u]][i];}}}voidinit(){memset(tr,0,sizeof tr);memset(fa,0,sizeof fa);memset(mk,0,sizeof mk);
idx =0;}intmain(){pre_do();int cas =1;while(scanf("%d",&n)&& n){init();for(int i =1; i <= n; i ++){scanf("%s", s);insert();}scanf("%s", s);int m =strlen(s);build();memset(dp, inf,sizeof dp);
dp[0][0]=0;for(int i =0; i < m; i ++){for(int j =0; j < idx; j ++){for(int k =0; k <4; k ++){int l = tr[j][k];if(mk[j]|| mk[l]|| dp[i][j]== inf)continue;
dp[i +1][l]=min(dp[i +1][l], dp[i][j]+(id[s[i]]!= k));}}}int ans = inf;for(int i =0; i < idx; i ++)
ans =min(ans, dp[m][i]);printf("Case %d: ", cas ++);if(ans == inf)printf("-1\n");elseprintf("%d\n", ans);}return0;}
题意给定 n 个子串 ti 四个字符,和一个主串 s,所有字符串仅包含 A,G,C,T,问最少需要修改几个字符,才使 s 中不包含任意一个 ti 字符串。n < 50, |s|<=1000, |ti<=20|.思路这是 y 总讲的状态机模型代码#include <bits/stdc++.h>using namespace std;#define db double#define ll long long#define Pir pair<in