题意:

给出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. Hibernate(六)一对一双向关联映射

    在上次的博文Hibernate从入门到精通(五)一对一单向关联映射中我们讲解了一下一对一单向关联映射, 这次我们继续讲解一下与之对应的一对一双向关联映射. 一对一双向关联 与一对一单向关联映 射所不同 ...

  2. POJ 1503 Integer Inquiry 简单大数相加

    Description One of the first users of BIT's new supercomputer was Chip Diller. He extended his explo ...

  3. 《University Calculus》-chape10-向量与空间几何学-向量夹角

    点积.向量夹角: 无论对于空间向量还是平面向量,我们所熟知的是:给出任意两个向量,我们都能够根据公式计算它们的夹角,但是这个夹角必须是将两个向量的起点重合后所夹成的小于等于π的角,可是,这是为什么呢? ...

  4. MFC去掉win7玻璃效果

    在MainFrame的OnCreate中添加以下代码 if (CWnd::OnCreate(lpCreateStruct) == -1) return -1; HINSTANCE hInstance ...

  5. openstack 控制节点大流量对外发包,nf_conntrack,table full droping packets

    某些人很MJJ,挂了N多代理来疯狂采集,把服务器带宽都耗尽了,没办法只好封掉一些! 目前发现的问题openStack kilo for ubuntu manuual运行一段时间后 云平台的控制节点p5 ...

  6. hdoj 3746 Cyclic Nacklace【KMP求在结尾加上多少个字符可以使字符串至少有两次循环】

    Cyclic Nacklace Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)T ...

  7. CSS3动画变形transition

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  8. Linux查看系统资源占用

    Linux查看系统资源占用 在系统维护的过程中,随时可能有需要查看 CPU和内存的使用率,并根据相应信息分析系统状况的需求.本文介绍一下几种常见的Linux系统资源查看命令. 1.总体内存占用的查看 ...

  9. 移植QT到ZedBoard(制作运行库镜像) 交叉编译 分类: ubuntu shell ZedBoard OpenCV 2014-11-08 18:49 219人阅读 评论(0) 收藏

    制作运行库 由于ubuntu的Qt运行库在/usr/local/Trolltech/Qt-4.7.3/下,由makefile可以看到引用运行库是 INCPATH = -I/usr//mkspecs/d ...

  10. 为Android GridView 设置行背景

    经常有这样的需求,你的功能图标要像一个个物品,摆放在书架上,像这样: 我的思路比较简单,重载GridView,在他绘制子视图前,先把背景绘制完成 1 2 3 4 5 6 7 8 9 10 11 12 ...