orz题解的Dp,竟然没调就1A了。。。。。
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <queue>
#include <vector>
using namespace std;
#define N 1010
#define Mod 1000000009
int n,m;
int Dp[N][110][11],id[30];
struct AcAuto{
int next[N][4],fail[N],Cover[N];
int tot,root;
int New_node()
{
for(int i=0;i<4;i++)
next[tot][i]=-1;
Cover[tot++]=0;
return tot-1;
}
void Init()
{
tot=0;
root=New_node();
}
void Insert(char *T)
{
int len=(int)strlen(T);
int now=root;
for(int i=0;i<len;i++)
{
int num=id[T[i]-'A'];
if(next[now][num]==-1)
next[now][num]=New_node();
now=next[now][num];
}
Cover[now]=len;
}
void Build_Failtree()
{
queue<int> Q;
fail[root]=root;
for(int i=0;i<4;i++)
{
if(next[root][i]==-1)
next[root][i]=root;
else
{
fail[next[root][i]]=root;
Q.push(next[root][i]);
}
}
while(!Q.empty())
{
int now=Q.front();Q.pop();
Cover[now]=max(Cover[now],Cover[fail[now]]);
for(int i=0;i<4;i++)
{
if(next[now][i]==-1)
next[now][i]=next[fail[now]][i];
else
{
fail[next[now][i]]=next[fail[now]][i];
Q.push(next[now][i]);
}
}
}
}
void Solve()
{
memset(Dp,0,sizeof(Dp));
Dp[0][0][0]=1;
for(int i=0;i<n;i++)
{
for(int j=0;j<tot;j++)
{
for(int k=0;k<10;k++)
{
for(int t=0;t<4;t++)
{
int nowj=next[j][t],nowi=i+1;
if(Cover[nowj]>=k+1)
Dp[nowi][nowj][0]=(Dp[nowi][nowj][0]+Dp[i][j][k])%Mod;
else
Dp[nowi][nowj][k+1]=(Dp[nowi][nowj][k+1]+Dp[i][j][k])%Mod;
}
}
}
}
int Ans=0;
for(int i=0;i<tot;i++)
Ans=(Ans+Dp[n][i][0])%Mod;
printf("%d\n",Ans);
return;
}
};
AcAuto A;
char S[20];
int main()
{
cin>>n>>m;
id[0]=0;id[2]=1;id['G'-'A']=2;id['T'-'A']=3;
A.Init();
for(int i=1;i<=m;i++)
{
scanf("%s",S);
A.Insert(S);
}
A.Build_Failtree();
A.Solve();
return 0;
}