Codeforces 86C Genetic engineering

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;
}


 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章