题意:

给出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. Python copy对象(copy与deepcopy)

    Python中的对象之间赋值时是按引用传递的,如果需要拷贝对象,需要使用标准库中的copy模块. 1. copy.copy 浅拷贝 只拷贝父对象,不会拷贝对象的内部的子对象. 2. copy.deep ...

  2. FBReader移植日记 第一天

    1.目标是创建两个工程,一个j2se的桌面软件,用于编辑和预览epub等格式的电子书,预览的窗口可以设置分辨率来模拟不同的设备,把编辑的结果实时的显示出来.另一个是Android的应用,用于阅读,管理 ...

  3. Bzoj 2818: Gcd 莫比乌斯,分块,欧拉函数,线性筛

    2818: Gcd Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 3241  Solved: 1437[Submit][Status][Discuss ...

  4. 从奥鹏一个答案提取页面 看jquery知识点

     http://oldlearn.open.com.cn/OEMSExercise/HomeworkReview.aspx?HomeworkId=9c034488-0a3d-4b9d-a6cc-e42 ...

  5. [转]jquery中使用event.target的几点

    转自: http://www.cnblogs.com/12go/archive/2011/12/28/2304502.html 1.this和event.target的区别: js中事件是会冒泡的,所 ...

  6. java 实现 DES加密 解密算法

    DES算法的入口参数有三个:Key.Data.Mode.其中Key为8个字节共64位,是DES算法的工作密钥:Data也为8个字节64位,是要被加密或被解密的数据:Mode为DES的工作方式,有两种: ...

  7. uva1393 Highways

    留坑(p.339) 已填(膜汪) 每条直线至少经过两个点,我们不妨在经过的所有点中的第二个点统计它 设f[i][j]表示i * j的答案,那么显然可以用f[i][j] = f[i - 1][j] + ...

  8. JetBrains发布了一款免费的.NET反编译器dotPeek

    Free .NET decompiler :: JetBrains dotPeek 主要的功能: Decompiling .NET 1.0-4.5 assemblies to C# Exporting ...

  9. ssl https服务 需要 php5.3以上

    php 5.2 升级 5.3 http://wdlinux.cn/bbs/viewthread.php?tid=37512&highlight=5.3 默认的升级不支持 pdo 升级前编辑升级 ...

  10. android 36 线程通信

    安卓中一个程序跑起来叫进程,进程中至少有一个主线程.主线程用于处理用户的触摸操作和将触摸操作事件分发给响应的控件.如果进行消耗时间操作,下载,磁盘读取文件,不润许在主线程操作,只能在工作线程操作.主线 ...