zoukankan      html  css  js  c++  java
  • 【[JSOI2007]文本生成器】

    (AC)机上的计数(dp)

    并没有想到反着求出不合法的串的个数,直接正面硬上

    (dp[i][j][0/1])表示匹配出的长度为(i),在(AC)机上位置为(j),没有/有匹配到一个完整串的方案数

    由于这个的长度是满足子结构的,可以直接(dp)求解

    注意结束标记会影响到所有能通过跳(fail)到达它的点,所以(Build)的时候预处理好

    代码

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<queue>
    #define re register
    #define maxn 60*105
    #define LL long long
    #define max(a,b) ((a)>(b)?(a):(b))
    #define min(a,b) ((a)<(b)?(a):(b))
    const int mod=10007;
    int fail[maxn],son[maxn][26],flag[maxn];
    inline int read()
    {
    	char c=getchar();
    	int x=0;
    	while(c<'0'||c>'9') c=getchar();
    	while(c>='0'&&c<='9') x=(x<<3)+(x<<1)+c-48,c=getchar();
    	return x;
    }
    char S[1005];
    int cnt,n,m;
    int dp[105][maxn][2];
    inline void ins()
    {
    	scanf("%s",S+1);
    	int len=strlen(S+1),now=0;
    	for(re int i=1;i<=len;i++)
    	{
    		if(!son[now][S[i]-'A']) son[now][S[i]-'A']=++cnt;
    		now=son[now][S[i]-'A'];
    	}
    	flag[now]=1;
    }
    inline void Build()
    {
    	std::queue<int> q;
    	for(re int i=0;i<26;i++) if(son[0][i]) q.push(son[0][i]);
    	while(!q.empty())
    	{
    		int k=q.front();
    		q.pop();
    		flag[k]|=flag[fail[k]];
    		for(re int i=0;i<26;i++)
    		if(son[k][i]) fail[son[k][i]]=son[fail[k]][i],q.push(son[k][i]);
    			else son[k][i]=son[fail[k]][i];
    	}
    }
    int main()
    {
    	n=read(),m=read();
    	for(re int i=1;i<=n;i++) ins();
    	Build();
    	dp[0][0][0]=1;
    	for(re int i=0;i<m;i++)
    		for(re int j=0;j<=cnt;j++)
    			for(re int o=0;o<2;o++)
    			{
    				if(!dp[i][j][o]) continue;
    				for(re int k=0;k<26;k++)
    					dp[i+1][son[j][k]][o|flag[son[j][k]]]+=dp[i][j][o],dp[i+1][son[j][k]][o|flag[son[j][k]]]%=mod;
    			}
    	int ans=0;
    	for(re int i=0;i<=cnt;i++)
    		ans+=dp[m][i][1],ans%=mod;
    	printf("%d
    ",ans);
    	return 0;
    }
    
  • 相关阅读:
    DP(动态规划)学习心得
    hloj#402 护卫队解题讨论
    hloj#168“倒牛奶”解题讨论
    贪心:畜栏预定
    区间问题
    离散化
    差分
    浏览器的工作原理幕后揭秘的部分笔迹摘要
    python之阶乘的小例子
    关于python中urllib.urlencode的时候出错:UnicodeEncodeError: ‘ascii’的记录
  • 原文地址:https://www.cnblogs.com/asuldb/p/10207909.html
Copyright © 2011-2022 走看看