AC自动机+DP。
这题和POJ2778神似。不同的是本题要求包含字串,而那POJ那一题要求不包含。
发现只要m一定,总数量是一定的,为 26m 。于是正难则反- -,用总数量减去不包含任何串的数量。
这题节点太多(最坏情况上千个),不能用矩阵做,于是DP。记f[i][j]表示以i节点为起点,长度为j的合法字符串方案数,往儿子DP即可。
#include<cstdio>
#include<queue>
#include<cstring>
#define L 105
#define N 60
#define MOD 10007
using namespace std;
int n, m, cnt;
long long f[N*L][L];
char s[L];
struct node
{
node *next[27], *fail;
bool flag;
int id;
node()
{
memset(next,NULL,sizeof(next));
fail=NULL;
flag=0;
id=++cnt;
}
};
struct ACAutoMaton
{
node *root;
void init()
{
root=new node;
root->fail=root;
}
void inser()
{
node *p=root;
for(int i = 0; s[i]; i++)
{
int c=s[i]-'A';
if(p->next[c]==NULL)
p->next[c]=new node;
p=p->next[c];
}
p->flag=1;
}
void build()
{
queue<node*> q;
for(int i = 0; i < 26; i++)
{
if(root->next[i])
{
root->next[i]->fail=root;
q.push(root->next[i]);
}
else
root->next[i]=root;
}
while(!q.empty())
{
node *u = q.front();
q.pop();
for(int i = 0; i < 26; i++)
{
if(u->next[i]==NULL)
{
u->next[i]=u->fail->next[i];
continue;
}
node *v = u->next[i], *t = u->fail;
q.push(v);
while(t!=root && t->next[i]==NULL)
t=t->fail;
v->fail=t->next[i]?t->next[i]:root;
v->flag|=v->fail->flag;
}
}
}
void dp_pre()
{
queue<node*> q;
q.push(root);
for(int i = 0; i < 26; i++)
if(!root->next[i]->flag)
f[root->id][1]++;
while(!q.empty())
{
node *u=q.front();
q.pop();
for(int i = 0; i < 26; i++)
{
node *v=u->next[i];
if(f[v->id][1])continue;
for(int i = 0; i < 26; i++)
if(!v->next[i]->flag)
f[v->id][1]++;
q.push(v);
}
}
}
void dp(node *p, int step)
{
int id=p->id;
if(f[id][step])return;
for(int i = 0; i < 26; i++)
{
if(p->next[i]->flag)continue;
dp(p->next[i],step-1);
f[id][step]=(f[id][step]+f[p->next[i]->id][step-1])%MOD;
}
}
}AC;
int main()
{
AC.init();
scanf("%d%d",&n,&m);
for(int i = 1; i <= n; i++)
{
scanf("%s",s);
AC.inser();
}
AC.build();
AC.dp_pre();
AC.dp(AC.root,m);
int tot=1, ans=f[AC.root->id][m];
for(int i = 1; i <= m; i++)tot=(tot*26)%MOD;
printf("%d\n",((tot-ans)%MOD+MOD)%MOD);
return 0;
}
本文介绍了一种结合AC自动机与动态规划(DP)的算法实现,用于解决特定字符串匹配问题。通过构建AC自动机并运用DP计算合法字符串方案数,最终求解在给定长度下不包含预设模式的字符串总数。

125

被折叠的 条评论
为什么被折叠?



