题意:

给出n个串,求任意长度为m的字符串包含串的个数的期望。(n<=8,m<=14,给定串的长度不超过12)。

Solution:

首先可以想到应该用概率DP,我们需要至少3维,dp[i][j][k]表示第i个数字为j,已经包含了k个串的概率.

然后,问题是找到状态转移的方法

由于是字符串相关,AC自动机应该是第一个想到的.

然后注意到,对于k个串的k,直接求并不好维护,也没办法判断重复的 .由于只有8个串,自然就想到用更简单的方法,用状态压缩来存已经包含了哪些串.

在建trie图的时候,要注意一个结点的状态应该是包含了它的fail节点的状态的.

从u到v的转移

dp[i+1][u][sta[u]|sta[v]]+=dp[i][v][sta[v]]

#include <iostream>
#include <queue>
#include <cstdio>
#include <string>
#include <cstring>
using namespace std;
const int SD = ;
const int MAXL = ;
struct Tire {
int next[MAXL][SD], fail[MAXL], eofs[MAXL];
int Root, cnt;
int newnode() {
for (int i = ; i < SD; i++) next[cnt][i] = -;
eofs[cnt++] = ;
return cnt - ;
}
void init() {
cnt = ;
Root = newnode();
}
void Ins (char buf[], int k) {
int len = strlen (buf);
int now = Root;
for (int i = ; i < len; i++) {
if (next[now][buf[i] - 'a'] == -)
next[now][buf[i] - 'a'] = newnode();
now = next[now][buf[i] - 'a'];
}
eofs[now] |= ( << k);
}
void build() {
queue<int> ql;
fail[Root] = Root;
for (int i = ; i < SD; i++) {
if (next[Root][i] == -)
next[Root][i] = Root;
else {
fail[next[Root][i]] = Root;
ql.push (next[Root][i]);
}
}
while (!ql.empty() ) {
int now = ql.front(); ql.pop();
eofs[now] |= eofs[fail[now]];
for (int i = ; i < SD; i++)
if (next[now][i] == -) {
next[now][i] = next[fail[now]][i];
}
else {
fail[next[now][i]] = next[fail[now]][i];
ql.push (next[now][i]);
}
}
}
} AC;
int Cs, n, m;
char s[];
double dp[][][ << ], tmp = . / ;
int main() {
scanf ("%d", &Cs);
while (Cs--) {
memset (dp, , sizeof dp);
AC.init();
scanf ("%d %d", &n, &m);
for (int i = ; i < n; i++) {
scanf ("%s", s);
AC.Ins (s, i);
}
AC.build(); dp[][][] = ;
for (int i = ; i < m; i++)
for (int u = ; u < AC.cnt; u++)
for (int st = ; st < ( << n); st++)
if (dp[i][u][st] > )
for (int j = ; j < SD; j++) {
int v = AC.next[u][j];
dp[i + ][v][st | AC.eofs[v]] += dp[i][u][st] * tmp;
} double ans = ;
for (int i = ; i < AC.cnt; i++)
for (int st = ; st < ( << n); st++)
if (dp[m][i][st] > ) {
int sum = ;
for (int k = ; k < n; k++)
if (st & ( << k) ) sum++;
ans += dp[m][i][st] * sum;
}
printf ("%.6f\n", ans);
}
}

WHU 1572 Cyy and Fzz (AC自动机 dp )的更多相关文章

  1. POJ1625 Censored!(AC自动机+DP)

    题目问长度m不包含一些不文明单词的字符串有多少个. 依然是水水的AC自动机+DP..做完后发现居然和POJ2778是一道题,回过头来看都水水的... dp[i][j]表示长度i(在自动机转移i步)且后 ...

  2. HDU2296 Ring(AC自动机+DP)

    题目是给几个带有价值的单词.而一个字符串的价值是 各单词在它里面出现次数*单词价值 的和,问长度不超过n的最大价值的字符串是什么? 依然是入门的AC自动机+DP题..不一样的是这题要输出具体方案,加个 ...

  3. HDU2457 DNA repair(AC自动机+DP)

    题目一串DNA最少需要修改几个基因使其不包含一些致病DNA片段. 这道题应该是AC自动机+DP的入门题了,有POJ2778基础不难写出来. dp[i][j]表示原DNA前i位(在AC自动机上转移i步) ...

  4. hdu 4117 GRE Words AC自动机DP

    题目:给出n个串,问最多能够选出多少个串,使得前面串是后面串的子串(按照输入顺序) 分析: 其实这题是这题SPOJ 7758. Growing Strings AC自动机DP的进阶版本,主题思想差不多 ...

  5. hdu 2457(ac自动机+dp)

    题意:容易理解... 分析:这是一道比较简单的ac自动机+dp的题了,直接上代码. 代码实现: #include<stdio.h> #include<string.h> #in ...

  6. HDU 2425 DNA repair (AC自动机+DP)

    DNA repair Time Limit: 5000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  7. HDU2296——Ring(AC自动机+DP)

    题意:输入N代表字符串长度,输入M代表喜欢的词语的个数,接下来是M个词语,然后是M个词语每个的价值.求字符串的最大价值.每个单词的价值就是单价*出现次数.单词可以重叠.如果不止一个答案,选择字典序最小 ...

  8. tyvj P1519 博彩游戏(AC自动机+DP滚动数组)

    P1519 博彩游戏 背景 Bob最近迷上了一个博彩游戏…… 描述 这个游戏的规则是这样的:每花一块钱可以得到一个随机数R,花上N块钱就可以得到一个随机序列:有M个序列,如果某个序列是产生的随机序列的 ...

  9. bzoj 1030 [JSOI2007]文本生成器(AC自动机+DP)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1030 [题意] 给n个小串,随机构造一个长为m的大串,一个串合法当且仅当包含一个或多个 ...

随机推荐

  1. (转载)shell中用date命令获取昨天、明天或者多天前的日期

    (转载)http://blog.sina.com.cn/s/blog_3e4774e30100p0yv.html 使用date命令获取日期很方便,最近需要获取当前日期的下一天日期在linux应该如何获 ...

  2. 15个值得开发人员关注的jQuery开发技巧和心得

    在这篇文章中,我们将介绍15个让你的jQuery更加有效的技巧,大部分关于性能提升的,希望大家能够喜欢! 1. 尽量使用最新版本的jQuery类库 jQuery项目中使用了大量的创新.最好的方法来提高 ...

  3. 使用VisualStudio进行单元测试之三

    私有方法需不需要测试,本文不做讨论.假设您也认为有时候,私有方法也需要进行测试,那就一起来看看如何进行私有方法的测试. 准备测试代码 测试用的代码还是前面测试时使用过的代码,不同之处就是在类中增加了一 ...

  4. JavaScript高级程序设计2.pdf

    第三章 基本概念 区分大小写 ECMAScript中的一切(变量.函数名和操作符)都区分大小写 标识符 指变量.函数.属性的名字或者函数的参数 第一个字符必须是一个字母.下划线或美元符号,其它字符可以 ...

  5. 在word 2013中输入latex公式

    注意:版权所有,转载请注明出处 向word输入LaTeX公式,插件有很多,前面在使用的是一个叫做Aurora的插件,结果不是免费的,用了一段时间就要收费是,所以就不用了,从网上找到别人的介绍,可以使用 ...

  6. java对Ldap操作2

    package ldap.pojo;import java.util.List;/** * @author 张亮  * ldap用户属性信息数据类 */public class LdapPersonI ...

  7. Just a Hook

      Just a Hook 题目大意:原来有N个铜棍, 一个人有种能力可以把一个区间的棍变成铜,银或者金的,价值分别是1,2,3, 最后求出总价值,没啥好说的,赤裸裸的线段树: Time Limit ...

  8. maven常用插件配置

    1.maven-jar-plugin插件 <!-- 排除资源文件中的properties文件,不需要打到jar中,后面通过assembly插件打包到conf目录中 --><plugi ...

  9. java poi操作excel 添加 锁定单元格保护

    Excel的book保护是很常用的,主要是不想让别人修改Excel的时候用.这样能够避免恶意随便修改数据,提高数据的可信度. 下面介绍JAVA POI来实现设置book保护: 使用HSSFSheet类 ...

  10. (配置)CKEditor+CKFinder+php上传配置,根据年月命名创建文件夹来存放

    CKEditor+CKFinder+php上传配置 新版本的CKEditor只提供了基本的文本编辑功能,上传模块由另一个组件CKFinder.这里主要记录CKFinder上传的一些参数配置,能够成功上 ...