Wireless Password HDU - 2825 AC自动机DP计数

给m个单词,问构造长为n且含有至少k个单词的串的种数

朴素的自动机上DP,遍历了自动机的所有状态,dp[i][j][k]:长为i的串匹配到状态j,出现k编码状态word的串的种数

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define ll long long
#define ull unsigned long long
#define pb push_back
#define FOR(a) for(int i=1;i<=a;i++)
const int inf=0x3f3f3f3f;
const int maxn=140+9; 
const int mod=20090717;

const int sigma=26;

int n,m,k;

int dp[30][110][1<<10];	
//dp[i][j][k]:长度为i的串匹配到状态j,出现了k状态word的串个数
int num[5005];	//num[i]:i有多少个二进制为1位

struct automata{
	int ch[maxn][sigma];
	int val[maxn];
	int f[maxn];
	int sz;

	int newnode(){
		memset(ch[sz],0,sizeof(ch[sz]));
		f[sz]=val[sz]=0;
		return sz++;
	}

	void init(){
		memset(val,0,sizeof(val));
		sz=0;
		newnode();
	}

	void insert(char *s,int v){	
		int u=0;
		int len=strlen(s);
		for(int i=0;iq;
		q.push(0);	
		while(!q.empty()){
			int u=q.front();q.pop();

			val[u]|=val[f[u]];

			for(int i=0;i0){
						for(int c=0;c<26;c++){
							int nxti=i+1;
							int nxtj=ch[j][c];
							int nxtp=(p|val[nxtj]);
							dp[nxti][nxtj][nxtp]+=dp[i][j][p];
							dp[nxti][nxtj][nxtp]%=mod;
						}
					}
				}
			}
		}
		int ans=0;
		for(int p=0;p<(1<

你可能感兴趣的:(AC_automata)