题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2825
题意:给出m个串,求一个长度为n的串包含至少m个串中的K个。问这样的串有多少个?
思路:f[i][j][k]表示长度为i、到达自动机上的j节点、包含的状态为k的种类数。转移时,从当前节点向其next节点转移。
struct node
{
int next[26],fail,st;
void init()
{
clr(next,-1);
fail=-1;
st=0;
}
};
node a[N];
int e,n,m,K,p[1300];
void init()
{
int i;
for(i=0;i<(1<<10);i++) p[i]=p[i>>1]+(i&1);
}
void insert(char s[],int t)
{
int i,k,p=0;
for(i=0;s[i];i++)
{
k=s[i]-'a';
if(a[p].next[k]==-1)
{
a[e].init();
a[p].next[k]=e++;
}
p=a[p].next[k];
}
a[p].st|=1<<t;
}
void build()
{
queue<int> Q;
int i,j,k,t,p,q;
Q.push(0);
while(!Q.empty())
{
k=Q.front();
Q.pop();
for(i=0;i<26;i++)
{
if(a[k].next[i]!=-1)
{
p=a[k].next[i];
q=a[k].fail;
if(q==-1) a[p].fail=0;
else a[p].fail=a[q].next[i];
a[p].st|=a[a[p].fail].st;
Q.push(p);
}
else
{
q=a[k].fail;
if(q==-1) a[k].next[i]=0;
else a[k].next[i]=a[q].next[i];
}
}
}
}
int f[30][150][1300];
void DP()
{
int i,j,k,t,x,y;
FOR0(i,n+1) FOR0(j,e) FOR0(k,(1<<m)) f[i][j][k]=0;
f[0][0][0]=1;
FOR0(i,n) FOR0(j,e) FOR0(k,(1<<m)) if(f[i][j][k])
{
FOR0(t,26)
{
x=a[j].next[t];
y=a[x].st;
(f[i+1][x][k|y]+=f[i][j][k])%=mod;
}
}
int ans=0;
FOR0(j,e) FOR0(k,(1<<m)) if(p[k]>=K)
{
ans+=f[n][j][k];
ans%=mod;
}
PR(ans);
}
int main()
{
init();
while(scanf("%d%d%d",&n,&m,&K),n||m||K)
{
a[0].init();
e=1;
char s[15];
int i;
FOR0(i,m) RD(s),insert(s,i);
build();
DP();
}
}