计蒜客-蒜场抽奖(AC自动机+状态压缩DP)


题解:题意不再说了,题目很清楚的。
思路:因为N<=10,所以考虑状态压缩 AC自动机中 val[1<<i]: 表示第i个字符串。AC自动机中fail指针是指当前后缀在其他串里面所能匹配的最长前缀的长度,然后我们在这里统计一下以该点结束所能包含的字符串的数量(就是在fail树中该点到根节点所经过的所有为单词结尾的点,在这里我们只要val[x] |= val[fail[x]]就行了,因为val[fail[x]]已经统计过 点fail[x]到根的值了)。
考虑dp[i][j][k]:表示长度为i,第j个状态点,k为包含的单词的状态, 是否存在。然后转移方程为:if( ch[m-1][j][k] ) ch[m][ ch[j][ char ] ][ k|val[ ch[j][char] ] ]=1;(char : 为第j个状态再往后走一步到达的状态);
我们的长度是一步一步走的,而且当前步数,仅有上一步确定,所以我们可以压缩步数为奇数偶数,变为:if( ch[ (m-1)&1 ][j][k] ) ch[ m&1 ][ ch[j][ char ] ][ k|val[ ch[j][char] ] ]=1;最后我们只要在第m步的每个状态包含不停字符串状态时的答案里面去最大值就行了。
参考代码:
#include<bits/stdc++.h>
using namespace std;
const int INF=0x3f3f3f3f;
const int maxn=;
int ch[maxn][],val[maxn],fail[maxn];
int w[],tot,n,m,Ans[maxn];
bool dp[][maxn][<<];
char s[]; void Init()
{
tot=;
memset(val,,sizeof val);
memset(ch[tot],,sizeof ch[tot]);
} void Insert(char *s,int x)
{
int len=strlen(s),u=;
for(int i=;i<len;++i)
{
int c=s[i]-'a';
if(!ch[u][c]) {ch[u][c]=tot++;memset(ch[tot],,sizeof ch[tot]);}
u=ch[u][c];
}
val[u]=<<x;
} void GetFail()
{
queue<int>q;
for(int i=;i<;++i)
if(ch[][i]) q.push(ch[][i]);
while(!q.empty())
{
int u=q.front();q.pop();
for(int i=;i<;++i)
{
int v=ch[u][i];
if(!v){ch[u][i]=ch[fail[u]][i];continue;}
q.push(v);
fail[v]=ch[fail[u]][i];
val[v]|=val[fail[v]];
}
}
} void Work()
{
dp[][][]=;
for(int i=;i<=m;++i)
{
memset(dp[i&],,sizeof dp[i&]);
for(int j=;j<tot;++j)
for(int k=;k<;++k)
for(int z=;z<(<<n);++z)
{
if(dp[(i-)&][j][z])
dp[i&][ch[j][k]][z|val[ch[j][k]]]=;
}
}
} int GetAns(int x)
{
int ans=;
for(int i=;i<n;++i)
if(x&(<<i)) ans+=w[i];
return ans;
} int main()
{
scanf("%d%d",&n,&m);
Init();
for(int i=;i<n;++i)
scanf("%s%d",s,w+i),Insert(s,i);
GetFail();
Work();
int res=-INF; for(int j=;j<(<<n);++j) Ans[j]=GetAns(j);
for(int i=;i<tot;++i)
for(int j=;j<(<<n);++j)
if(dp[m&][i][j]) res=max(res,Ans[j]); if(res<) puts("Unhappy!");
else printf("%d\n",res); return ;
}
计蒜客-蒜场抽奖(AC自动机+状态压缩DP)的更多相关文章
- HDU 4511 (AC自动机+状态压缩DP)
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4511 题目大意:从1走到N,中间可以选择性经过某些点,比如1->N,或1->2-> ...
- POJ 3691 (AC自动机+状态压缩DP)
题目链接: http://poj.org/problem?id=3691 题目大意:给定N个致病DNA片段以及一个最终DNA片段.问最终DNA片段最少修改多少个字符,使得不包含任一致病DNA. 解题 ...
- hdu 4057(ac自动机+状态压缩dp)
题意:容易理解... 分析:题目中给的模式串的个数最多为10个,于是想到用状态压缩dp来做,它的状态范围为1-2^9,所以最大为2^10-1,那我们可以用:dp[i][j][k]表示长度为i,在tri ...
- bzoj1195 神奇的ac自动机+状态压缩dp
/* 难的不是ac自动机,是状态压缩dp 之前做了一两题类似题目,感觉理解的还不够透彻 */ #include<iostream> #include<cstdio> #incl ...
- HDU 4758 Walk Through Squares( AC自动机 + 状态压缩DP )
题意:给你两个串A,B, 问一个串长为M+N且包含A和B且恰好包含M个R的字符串有多少种组合方式,所有字符串中均只含有字符L和R. dp[i][j][k][S]表示串长为i,有j个R,在自动机中的状态 ...
- HDU 4057 Rescue the Rabbit ( AC自动机 + 状态压缩DP )
模板来自notonlysuccess. 模式串只有10个,并且重复出现的分值不累加,因此很容易想到状态压缩. 将模式串加入AC自动机,最多有10*100个状态. dp[i][j][k]:串长为i,在T ...
- hdu 2825(ac自动机+状态压缩dp)
题意:容易理解... 分析:在做这道题之前我做了hdu 4057,都是同一种类型的题,因为题中给的模式串的个数最多只能为10个,所以我们就很容易想到用状态压缩来做,但是开始的时候我的代码超时了dp时我 ...
- 计蒜客 疑似病毒 (AC自动机 + 可达矩阵)
链接 : Here! 背景 : 开始我同学是用 AC自动机 + DP 的方法来做这道题, 这道题的标签是 AC自动机, 动态规划, 矩阵, 按道理来说 AC自动机 + DP 应该是能过的, 但是他不幸 ...
- 【bzoj1195】[HNOI2006]最短母串 AC自动机+状态压缩+BFS最短路
原文地址:http://www.cnblogs.com/GXZlegend/p/6825226.html 题目描述 给定n个字符串(S1,S2,„,Sn),要求找到一个最短的字符串T,使得这n个字符串 ...
随机推荐
- 如何提高web应用的吞吐量
这篇博文所列举的优化手段是针对比较传统项目,但是想提高系统的吞吐量现在时髦的技术还是那些前后端未分离, 使用nginx当成静态资源服务器去代理我们的静态资源 是谁限制了Throughput? 当我们对 ...
- Linux下mysql 多实例安装配置
首先我们要清楚什么是多实例?所谓多实例就是用多个配置文件来启动多个不同端口的进程,以不同的端口的形式为外提供服务.明白了多实例 我们下面的操作和配置就一目了然了首先我们要安装一套基础的应用程序,也就是 ...
- centos6官网镜像dvd1和dvd2的解释
- RabbitMQ学习笔记之五种模式及消息确认机制
本文详细介绍简单模式Simple.工作模式Work.发布订阅模式Publish/Subscribe.Topic.Routing. Maven依赖引用 <dependencies> < ...
- Redis的内存淘汰策略
Redis占用内存大小 我们知道Redis是基于内存的key-value数据库,因为系统的内存大小有限,所以我们在使用Redis的时候可以配置Redis能使用的最大的内存大小. 1.通过配置文件配置 ...
- nexus https proxy
- MYSQLnavicat绿色版工具下载
MYSql远程连接工具navicat工具:https://pan.baidu.com/s/1RU_8FCX7yCseAFRhn4voAQ
- python线程条件变量Condition(31)
对于线程与线程之间的交互我们在前面的文章已经介绍了 python 互斥锁Lock / python事件Event , 今天继续介绍一种线程交互方式 – 线程条件变量Condition. 一.线程条件变 ...
- H3C交换机DHCP基础配置案例 v7版本
一.需求 要求在Switch A上配置DHCP服务器功能实现:• 为网络内的客户端动态分配 10.1.1.0/24 网段内的 IP 地址.租用有效期限. DNS 信息.网关地址等配置信息:• 根据 S ...
- PowerMock学习(七)之Mock Constructor的使用
前言 我们在编码的时候,总习惯在构造器中传参数,那么在powermock中是怎么模拟带参数构造的呢,这并不难. 模拟场景 我们先模拟这样一个场景,通过dao中的传入一个是布尔类型(是否加载)和一个枚举 ...