const double esp = 1e-6;
int dp[1009][1009];
int cnt;
struct trie
{
trie *ch[4];
trie *fail;
int id;
bool end;
void init()
{
memset(ch, NULL, sizeof(ch));
fail = NULL;
id = cnt;
end = false;
}
}t[1009], *root;
int map(char ch)
{
if(ch=='A') return 0;
else if(ch=='C') return 1;
else if(ch=='G') return 2;
else return 3;
}
void insert(char *s)
{
trie *p = &t[0];
for(int i=0; s[i]; i++)
{
int k = map(s[i]);
if(p->ch[k]==NULL)
{
t[cnt].init();
p->ch[k] = &t[cnt++];
}
p = p->ch[k];
}
p->end = true;
}
queue<trie*>q;
void build_fail()
{
q.push(root);
root->fail = root;
while(!q.empty())
{
trie *p = q.front(); q.pop();
for(int k=0; k<4; k++)
if(p->ch[k]!=NULL)
{
q.push(p->ch[k]);
if(p==root)
{
p->ch[k]->fail = root;
if( p->ch[k]->fail->end == true )
p->ch[k]->end = true;
continue;
}
trie *tmp = p->fail;
while( tmp!=root && tmp->ch[k]==NULL)
tmp = tmp->fail;
if(tmp->ch[k]) p->ch[k]->fail = tmp->ch[k];
else p->ch[k]->fail = root;
if( p->ch[k]->fail->end == true )
p->ch[k]->end = true;
}
else
{
p->ch[k] = p->fail->ch[k];
}
}
}
inline void updata(int &a, int b)
{if(a < 0 || b < a) a = b;}
int main()
{
int n, ca = 0;
char str[1009];
while(scanf("%d", &n), n)
{
cnt = 0;
t[cnt++].init();
root = &t[0];
while(n--)
{
scanf("%s", str);
insert(str);
}
build_fail();
scanf("%s", str);
int len = strlen(str);
memset(dp, -1, sizeof(dp));
dp[0][0] = 0;
for(int i=0; i<len; i++)
for(int j=0; j<cnt; j++)
if(dp[i][j]>=0 && t[j].end==false)
{
for(int k=0; k<4; k++)
{
int tmp = 1-(k==map(str[i]));
if(t[j].ch[k]==NULL)
updata(dp[i+1][0], dp[i][j]+tmp);
else if(t[j].ch[k]->end==false)
updata(dp[i+1][ t[j].ch[k]->id ], dp[i][j]+tmp);
}
}
int ans = -1;
for(int i = 0; i < cnt; i ++)
if(dp[len][i] >= 0) updata(ans, dp[len][i]);
printf("Case %d: %d\n",++ca, ans);
}
return 0;
}
POJ-3691-ac自动机+dp
最新推荐文章于 2022-02-25 19:38:17 发布