题解:题意不再说了,题目很清楚的。

思路:因为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)的更多相关文章

  1. HDU 4511 (AC自动机+状态压缩DP)

    题目链接:  http://acm.hdu.edu.cn/showproblem.php?pid=4511 题目大意:从1走到N,中间可以选择性经过某些点,比如1->N,或1->2-> ...

  2. POJ 3691 (AC自动机+状态压缩DP)

    题目链接:  http://poj.org/problem?id=3691 题目大意:给定N个致病DNA片段以及一个最终DNA片段.问最终DNA片段最少修改多少个字符,使得不包含任一致病DNA. 解题 ...

  3. hdu 4057(ac自动机+状态压缩dp)

    题意:容易理解... 分析:题目中给的模式串的个数最多为10个,于是想到用状态压缩dp来做,它的状态范围为1-2^9,所以最大为2^10-1,那我们可以用:dp[i][j][k]表示长度为i,在tri ...

  4. bzoj1195 神奇的ac自动机+状态压缩dp

    /* 难的不是ac自动机,是状态压缩dp 之前做了一两题类似题目,感觉理解的还不够透彻 */ #include<iostream> #include<cstdio> #incl ...

  5. 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,在自动机中的状态 ...

  6. HDU 4057 Rescue the Rabbit ( AC自动机 + 状态压缩DP )

    模板来自notonlysuccess. 模式串只有10个,并且重复出现的分值不累加,因此很容易想到状态压缩. 将模式串加入AC自动机,最多有10*100个状态. dp[i][j][k]:串长为i,在T ...

  7. hdu 2825(ac自动机+状态压缩dp)

    题意:容易理解... 分析:在做这道题之前我做了hdu 4057,都是同一种类型的题,因为题中给的模式串的个数最多只能为10个,所以我们就很容易想到用状态压缩来做,但是开始的时候我的代码超时了dp时我 ...

  8. 计蒜客 疑似病毒 (AC自动机 + 可达矩阵)

    链接 : Here! 背景 : 开始我同学是用 AC自动机 + DP 的方法来做这道题, 这道题的标签是 AC自动机, 动态规划, 矩阵, 按道理来说 AC自动机 + DP 应该是能过的, 但是他不幸 ...

  9. 【bzoj1195】[HNOI2006]最短母串 AC自动机+状态压缩+BFS最短路

    原文地址:http://www.cnblogs.com/GXZlegend/p/6825226.html 题目描述 给定n个字符串(S1,S2,„,Sn),要求找到一个最短的字符串T,使得这n个字符串 ...

随机推荐

  1. MySQL57安装与设置

    安装MySQL 添加mysql源 [root@localhost ~]# rpm -ivh http://repo.mysql.com//mysql57-community-release-el7-7 ...

  2. Junit使用方法

    Junit使用方法 步骤: 定义 一个测试类(测试用例) 建议 测试类名:被测试类名+Test 包名:xxx.xxx.xxx.test 测试方法 建议: 方法名:test测试的方法名 返回值: voi ...

  3. python机器学习——逻辑回归

    我们知道感知器算法对于不能完全线性分割的数据是无能为力的,在这一篇将会介绍另一种非常有效的二分类模型--逻辑回归.在分类任务中,它被广泛使用 逻辑回归是一个分类模型,在实现之前我们先介绍几个概念: 几 ...

  4. thinkphp 比RBAC更好的权限认证方式(Auth类认证)

    Auth 类已经在ThinkPHP代码仓库中存在很久了,但是因为一直没有出过它的教程, 很少人知道它, 它其实比RBAC更方便 . RBAC是按节点进行认证的,如果要控制比节点更细的权限就有点困难了, ...

  5. [剑指offer] 二叉搜索树的后序遍历序列 (由1个后续遍历的数组判断它是不是BST)

    ①题目 输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果.如果是则输出Yes,否则输出No.假设输入的数组的任意两个数字都互不相同. ②思路 1.后续遍历的数组里,最后一个元素是根. 2 ...

  6. 学习Java第一步:安装Intellij IDEA和JDK

    注:其实真正学习一门新语言的第一步并不是安装开发工具,我是C#转JAVA,有一点编程经验了,所以可以直接跳过前面几步,直接上IDE. 1.下载IntelliJ IDEA [官网] http://www ...

  7. ZeroC ICE的远程调用框架

    想搞清楚slice为我们生成了什么样的框架代码,就先搞明白Ice的远程调用框架暗中为我们做了些什么? Ice将Ice Object的方法调用分为三个阶段(或步骤),分别是begin,process和e ...

  8. SQL中Truncate的用法

    SQL中Truncate的用法转自:http://www.studyofnet.com/news/555.html本文导读:删除表中的数据的方法有delete,truncate, 其中TRUNCATE ...

  9. 【论文阅读】CornerNet: Detecting Objects as Paired Keypoints

    以下内容将介绍ECCV2018的一篇目标检测的文章<CornerNet: Detecting Objects as Paired Keypoints>.该文章讲述了一个老子就是不用anch ...

  10. 2019-11-24:postgresql数据库安装,最后报错failed to load SQLModule 问题的解决方案

    安装环境:Windows 10 问题描述:Failed to load sql modules into the database cluster 原因在于 Postgresql 没有安装完全. 解决 ...