hdu2825Wireless Password(ac+dp)
状压dp+ac
dp[i+1][next[j]][st|tt]表示第i+1长度结点为next[j]状态为st|tt的时候的ans;
dp[i+1][next[j]][st|tt]+=dp[i][j][tt]; st记录当前结点是否为给定单词的结束点
后一维用01状态表示截止到目前结点为止所包含的单词数量。
需要修改ac模板的一个地方,val[u]|=val[fail[u]];
#include <iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<stdlib.h>
#include<vector>
#include<cmath>
#include<queue>
#include<set>
using namespace std;
#define N 115
#define LL long long
#define INF 0xfffffff
const double eps = 1e-;
const double pi = acos(-1.0);
const double inf = ~0u>>;
const int child_num = ;
const int mod = ;
class AC
{
private:
int ch[N][child_num];
int fail[N];
int Q[N];
int val[N];
int sz;
int id[];
int dp[][N][<<];
public:
void init()
{
fail[] =;
for(int i = ;i < child_num ; i++)
id[i+'a'] = i;
}
void reset()
{
memset(val,,sizeof(val));
memset(ch[],,sizeof(ch[]));
//memset(fail,0,sizeof(fail));
sz = ;
}
void insert(char *a,int key)
{
int p = ;
for(; *a ; a++)
{
int d = id[*a];
if(ch[p][d]==)
{
memset(ch[sz],,sizeof(ch[sz]));
ch[p][d] = sz++;
}
p = ch[p][d];
}
val[p] = (<<key);
}
void construct()
{
int i,head=,tail = ;
for(i = ;i < child_num ; i++)
{
if(ch[][i])
{
fail[ch[][i]] = ;
Q[tail++] = ch[][i];
}
}
while(head!=tail)
{
int u = Q[head++];
val[u]|=val[fail[u]];
for(i = ;i < child_num ;i++)
{
if(ch[u][i])
{
fail[ch[u][i]] = ch[fail[u]][i];
Q[tail++] = ch[u][i];
}
else ch[u][i] = ch[fail[u]][i];
}
}
}
void work(int n,int k,int m)
{
int i,j,g,o;
for(i = ; i <= n ;i++)
for(j = ; j <= sz ; j++)
for(g = ;g <=(<<m) ; g++)
dp[i][j][g] = ;
dp[][][] = ;
for(i = ; i < n ;i++)
for(j = ; j < sz ; j++)
{
for(int e = ; e < (<<m) ; e++)
{
if(!dp[i][j][e]) continue;
for(g = ;g < child_num ; g++)
{
o = ;
if(val[ch[j][g]])
{
o = val[ch[j][g]];
}
dp[i+][ch[j][g]][e|o]=(dp[i+][ch[j][g]][e|o]+dp[i][j][e])%mod;
}
}
}
int ans = ;
for(i = ; i < sz;i ++)
{
for(j = ;j < (<<m) ; j++)
{
if(!dp[n][i][j]) continue;
int o = ;
for(g = ;g < m ; g++)
if(j&(<<g)) o++;
if(o>=k)
ans = (ans+dp[n][i][j])%mod;
}
}
printf("%d\n",ans);
}
}ac;
char vir[];
int main()
{
int n,m,k,i;
ac.init();
while(scanf("%d%d%d",&n,&m,&k)!=EOF)
{
if(!n&&!m&&!k) break;
ac.reset();
for(i = ; i <= m; i++)
{
scanf("%s",vir);
ac.insert(vir,i-);
}
ac.construct();
ac.work(n,k,m);
}
return ;
}
hdu2825Wireless Password(ac+dp)的更多相关文章
- 【hdu2825-Wireless Password】AC自动机+DP
http://acm.hust.edu.cn/vjudge/problem/16883 题意:要构造一个长度为n的字符串,然后有m模板串构成一个集合(m<=10),构造出来的字符串至少含有k种模 ...
- 【HDU2825】Wireless Password (AC自动机+状压DP)
Wireless Password Time Limit: 1000MS Memory Limit: 32768KB 64bit IO Format: %I64d & %I64u De ...
- hdu 2825 Wireless Password(ac自己主动机&dp)
Wireless Password Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others ...
- HDU - 2825 Wireless Password(AC自己主动机+DP)
Description Liyuan lives in a old apartment. One day, he suddenly found that there was a wireless ne ...
- hdu_2825_Wireless Password(AC自动机+状压DP)
题目链接:hdu_2825_Wireless Password 题意: 给你m个串,问长度为n至少含k个串的字符串有多少个 题解: 设dp[i][j][k]表示考虑到长度为i,第j个自动机的节点,含有 ...
- HDU2825 Wireless Password —— AC自动机 + 状压DP
题目链接:https://vjudge.net/problem/HDU-2825 Wireless Password Time Limit: 2000/1000 MS (Java/Others) ...
- HDU 2825 Wireless Password (AC自己主动机,DP)
pid=2825">http://acm.hdu.edu.cn/showproblem.php? pid=2825 Wireless Password Time Limit: 2000 ...
- hdu2825 Wireless Password(AC自动机+状压dp)
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission ...
- HDU-2825 Wireless Password(AC自动机+状压DP)
题目大意:给一系列字符串,用小写字母构造出长度为n的至少包含k个字符串的字符串,求能构造出的个数. 题目分析:在AC自动机上走n步,至少经过k个单词节点,求有多少种走法. 代码如下: # includ ...
随机推荐
- JMeter学习-007-JMeter 断言实例之一 - 响应断言
之前的文章中已经对如何录制 web 的请求进行了详细的描述,敬请参阅:JMeter学习-004-WEB脚本入门实战 同时,我们的手机应用(例如:京东.天猫.唯品会.携程.易迅 等等 App)所发出的请 ...
- 记录一次项目中使用memcatch添加端口以及自动运行
具体原因:多个项目同时使用一个memcatch服务情况需要分别为项目添加端口,如果只有一个项目使用则不需要去修改端口(memcatch有默认端口),当然已可以去修改默认端口. 下面我记录下我自己的使用 ...
- 详解php的curl几个函数
关于php的curl一系列函数,这里解释一下它们的作用. 在html中,我们可以通过form设置http的post和get提交,但假如我们获取的数据不是从html中来的,而是php脚本主动向其他服务器 ...
- Python基础、collections补充
collections collections是Python数据类型的补充,可以实现Counter计数.可命名元组(namedtuple).默认字典.有序字典.双向队列等功能 参考:http://py ...
- Python之路-python(面向对象一)
一.面向对象介绍 二.为什么要用面向对象开发 三.封装.继承.多态.类.方法 面向过程和面向对象的区别 编程范式: 一般情况下,拿到一个项目不同的两个人有不同的编写方式(相同的是固定的语法.数据结构) ...
- PL/SQL不支持64位Oracle Client 解决办法
解决X64操作系统PL/SQL连接报错问题 make sure you have the 32 bits oracle client installed 说明PLSQL Developer并不支持Or ...
- raw socket
一个很newbee的例子,可惜还得改 import sys import time import socket import struct import random def SendPacketDa ...
- Centos 安装 Java
建立文件夹 进入/usr/文件夹下,建立一个文件,我这里是java文件夹,将jdk-8u45-linux-x64.tar.gz复制到/usr/java文件夹下 解压文件 解压指令为:tar -zxvf ...
- 使用NetBeans搭建基于Spring框架的Web应用
NetBeans下载链接:https://netbeans.org/. 第一步:选择“文件”菜单下的“新建项目”: 第二步:类别选择“Java Web”,项目选择“Web应用程序”,单击“下一步”: ...
- Openstack命令行创建不同vlan段虚拟机
默认使用nova-network的vlan模式,但是在使用默认的dashboard的时候,不能指定创建的虚拟机的使用网段,固定IP地址. 实际上该功能是在存在的,只是openstack的dashbbo ...