zoukankan      html  css  js  c++  java
  • 【BZOJ1559】[JSOI2009]密码(AC自动机,动态规划,搜索)

    【BZOJ1559】[JSOI2009]密码(AC自动机,动态规划,搜索)

    题面

    BZOJ
    洛谷

    题解

    首先求方案数显然是构建(AC)自动机之后再状压(dp),似乎没有什么好讲的。
    现在考虑答案小于(42)的时候的怎么输出方案。
    首先明白这样一点,如果一个位置可以不属于任何一个字符串而独立出来,那么它就可以贡献(26)种方案,再加之其它的字符串可以随意调换顺序,因此不可能有一个位置可以随意填放。所以这样的答案必定是所有(n)个字符串全部紧密的贴在一起形成的,直接(O(n!))爆搜即可。
    爆搜什么的懒得写了,就这样吧。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<queue>
    using namespace std;
    #define ll long long
    inline int read()
    {
    	int x=0;bool t=false;char ch=getchar();
    	while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
    	if(ch=='-')t=true,ch=getchar();
    	while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
    	return t?-x:x;
    }
    char ch[20];
    struct Node{int vis[26],fail,lt;}t[200];
    int L,n,tot;ll f[26][105][1<<10],ans;
    void insert(char *ch,int id)
    {
    	int now=0,l=strlen(ch+1);
    	for(int i=1;i<=l;++i)
    	{
    		if(!t[now].vis[ch[i]-97])
    			t[now].vis[ch[i]-97]=++tot;
    		now=t[now].vis[ch[i]-97];
    	}
    	t[now].lt=1<<id;
    }
    void Build()
    {
    	queue<int> Q;
    	for(int i=0;i<26;++i)
    		if(t[0].vis[i])Q.push(t[0].vis[i]);
    	while(!Q.empty())
    	{
    		int u=Q.front();Q.pop();
    		for(int i=0;i<26;++i)
    			if(t[u].vis[i])
    				t[t[u].vis[i]].fail=t[t[u].fail].vis[i],Q.push(t[u].vis[i]);
    			else t[u].vis[i]=t[t[u].fail].vis[i];
    		t[u].lt|=t[t[u].fail].lt;
    	}
    }
    int main()
    {
    	L=read();n=read();
    	for(int i=0;i<n;++i)scanf("%s",ch+1),insert(ch,i);
    	Build();f[0][0][0]=1;
    	for(int i=1;i<=L;++i)
    		for(int j=0;j<=tot;++j)
    			for(int l=0;l<1<<n;++l)
    				if(f[i-1][j][l])
    					for(int k=0;k<26;++k)
    						f[i][t[j].vis[k]][l|t[t[j].vis[k]].lt]+=f[i-1][j][l];
    	for(int i=0;i<=tot;++i)ans+=f[L][i][(1<<n)-1];
    	printf("%lld
    ",ans);
    	return 0;
    }
    
    
  • 相关阅读:
    Mysql删除数据库中所有表
    MySQL出现2059错误
    .NetCore笔记
    PLSql中文乱码
    Oracle误删除数据恢复。Oracle删除后恢复数据
    ora-28000:the account is locked,Oracle修改密码有效期,Oracle设置密码不过期
    Linux 常用命令
    Razor
    ORA-01578: ORACLE 数据块损坏 (文件号 13, 块号 2415081) ORA-01110: 数据文件XXXXXX
    ORA-01033:ORACLE initialization or shutdown
  • 原文地址:https://www.cnblogs.com/cjyyb/p/9781157.html
Copyright © 2011-2022 走看看