题意:给出一个字母表以及每个字母出现的概率。再给出一些模板串S。从字母表中每次随机拿出一个字母,一共拿L次组成一个产度为L的串,

问这个串不包含S中任何一个串的概率为多少?

析:先构造一个AC自动机,然后随机生成L个字母,就是在AC自动机的某个结点走多少步,dp[i][j] 表示在 i 结点,并且剩下 j 步,

然后记忆化搜索就OK了。

代码如下:

#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <cstdio>
#include <string>
#include <cstdlib>
#include <cmath>
#include <iostream>
#include <cstring>
#include <set>
#include <queue>
#include <algorithm>
#include <vector>
#include <map>
#include <cctype>
#include <cmath>
#include <stack>
#include <sstream>
#define debug() puts("++++");
#define gcd(a, b) __gcd(a, b)
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define freopenr freopen("in.txt", "r", stdin)
#define freopenw freopen("out.txt", "w", stdout)
using namespace std; typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int, int> P;
const int INF = 0x3f3f3f3f;
const LL LNF = 1e16;
const double inf = 0x3f3f3f3f3f3f;
const double PI = acos(-1.0);
const double eps = 1e-8;
const int maxn = 1e5 + 10;
const int mod = 1e9 + 7;
const int dr[] = {-1, 0, 1, 0};
const int dc[] = {0, 1, 0, -1};
const char *de[] = {"0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111", "1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111"};
int n, m;
const int mon[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
const int monn[] = {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
inline bool is_in(int r, int c){
return r >= 0 && r < n && c >= 0 && c < m;
}
const int maxnode = 20 * 20 + 10;
const int sigma_size = 128; struct Aho_Corasick{
int ch[maxnode][sigma_size];
int f[maxnode];
bool match[maxnode];
int sz;
void init(){ sz = 1; memset(ch[0], 0, sizeof ch[0]); } void insert(char *s){
int u = 0;
for(int i = 0; s[i]; ++i){
int c = s[i];
if(!ch[u][c]){
memset(ch[sz], 0, sizeof ch[sz]);
match[sz] = 0;
ch[u][c] = sz++;
}
u = ch[u][c];
}
match[u] = true;
} int getFail(){
queue<int> q;
f[0] = 0;
for(int c = 0; c < sigma_size; ++c){
int u = ch[0][c];
if(u){ f[u] = 0; q.push(u); }
} while(!q.empty()){
int r = q.front(); q.pop();
for(int c = 0; c < sigma_size; ++c){
int u = ch[r][c];
if(!u){ ch[r][c] = ch[f[r]][c]; continue; }
q.push(u);
int v = f[r];
while(v && !ch[v][c]) v = f[v];
f[u] = ch[v][c];
match[u] |= match[f[u]];
}
}
} };
Aho_Corasick ac;
double dp[maxnode][110];
bool vis[maxnode][110];
char s[100];
struct Node{
int x; double p;
};
vector<Node> v; double dfs(int u, int L){
if(!L) return 1.0;
double &ans = dp[u][L];
if(vis[u][L]) return ans;
vis[u][L] = 1;
ans = 0.0;
for(int i = 0; i < n; ++i){
int c = v[i].x;
if(!ac.match[ac.ch[u][c]]) ans += dfs(ac.ch[u][c], L-1) * v[i].p;
}
return ans;
} int main(){
int T; cin >> T;
for(int kase = 1; kase <= T; ++kase){
scanf("%d", &n);
ac.init();
for(int i = 0; i < n; ++i){
scanf("%s", s);
ac.insert(s);
}
ac.getFail();
scanf("%d", &n);
v.clear();
for(int i = 0; i < n; ++i){
double pp;
scanf("%s %lf", s, &pp);
v.push_back((Node){s[0], pp});
}
int L;
scanf("%d", &L);
memset(vis, 0, sizeof vis);
printf("Case #%d: %f\n", kase, dfs(0, L));
}
return 0;
}

  

UVa 11468 Substring (AC自动机+概率DP)的更多相关文章

  1. UVA11468 Substring --- AC自动机 + 概率DP

    UVA11468 Substring 题目描述: 给定一些子串T1...Tn 每次随机选择一个字符(概率会给出) 构造一个长为n的串S,求T1...Tn不是S的子串的概率 直接把T1...Tn建成AC ...

  2. uva 11468 - Substring(AC自己主动机+概率)

    题目链接:uva 11468 - Substring 题目大意:给出一些字符和各自字符相应的选择概率.随机选择L次后得到一个长度为L的字符串,要求该字符串不包括随意一个子串的概率. 解题思路:构造AC ...

  3. Substring UVA - 11468 AC自动机+概率DP

    题意: 给出一些字符和各自对应的选择概率,随机选择L次后得到一个长度为L的随机字符串S. 给出K个模板串,计算S不包含任何一个模板串的概率 dp[i][j]表示走到AC自动机 i 这个节点 还需要走 ...

  4. UVa 11468 (AC自动机 概率DP) Substring

    将K个模板串构成一个AC自动机,那些能匹配到的单词节点都称之为禁止节点. 然后问题就变成了在Tire树上走L步且不经过禁止节点的概率. 根据全概率公式用记忆化搜索求解. #include <cs ...

  5. UVA 11468【AC自动机+DP】

    dp[i][j]表示走了i步走到j结点的概率.初始值dp[0][0] = 1.当走到的结点不是单词尾结点时,才能走过去. !end[i]&&last[i] == root时,该结点才可 ...

  6. 2016ACM/ICPC亚洲区沈阳站H - Guessing the Dice Roll HDU - 5955 ac自动机+概率dp+高斯消元

    http://acm.hdu.edu.cn/showproblem.php?pid=5955 题意:给你长度为l的n组数,每个数1-6,每次扔色子,问你每个串第一次被匹配的概率是多少 题解:先建成ac ...

  7. 【BZOJ1444】[Jsoi2009]有趣的游戏 AC自动机+概率DP+矩阵乘法

    [BZOJ1444][Jsoi2009]有趣的游戏 Description Input 注意 是0<=P Output Sample Input Sample Output HINT  30%的 ...

  8. bzoj1444 有趣的游戏(AC自动机+概率dp)

    题意: 给定n个长度为l的模式串,现在要用前m个大写字母生成一个随机串,每个字符有自己的出现几率,第一次出现的字符串获胜,求最终每个字符串的获胜几率. 分析: 容易想到先把所有的字符串建成一个AC自动 ...

  9. BZOJ1444[Jsoi2009]有趣的游戏——AC自动机+概率DP+矩阵乘法

    题目描述 输入 注意 是0<=P, n , l, m≤ 10. 输出 样例输入 input 1 3 2 2 1 2 1 2 AB BA AA input 2 3 4 2 1 2 1 2 AABA ...

随机推荐

  1. 解决COMODO Internet Security更新慢或失败的问题

    方法一: COMODO 默认更新服务器只有一个:http://download.comodo.com/ 我电信网络更新速度非常慢: 实在没有办法了,找到了几个更新服务器: http://eu1.dow ...

  2. 分享知识-快乐自己:SSH 整合 Demo

    楼主A: XML 版 SSH整合Demo https://github.com/MlqBeginner/BlogGardenWarehouse/blob/master/SSH%E6%95%B4%E5% ...

  3. Python基础-网络编程request使用

    import requests#get请求 url = "http://127.0.0.1:8000/login" data={"username":" ...

  4. FileInputStream 把文件作为字节流进行读操作

    //把文件作为字节流进行读操作 FileInputStream in = new FileInputStream(filename);//FileInputStream具体实现了在文件上读取数据

  5. freeMarker(一)——freeMarker简介

    学习笔记,选自freeMarker中文文档,译自 Email: ddekany at users.sourceforge.net FreeMarker简介: FreeMarker 是一款 模板引擎: ...

  6. Metasploit的使用下篇——漏洞攻击

    一.上文总结 上篇当中主要通过开启的端口对目标主机进行攻击,最后成功做到了连接不过却不能查看到telnet的登陆用户名和密码,目前来看有两个原因:第一.我对于靶机telnet的设置有问题,没有设置相应 ...

  7. 【JVM】java棧

    java棧和函数调用的关系图 [名词解释]--->java棧是一块线程的私有空间--->java的棧是先进后出的数据结构.函数返回,则该函数的棧帧被弹出.--->一个函数对应一个棧帧 ...

  8. ACM学习历程—UESTC 1219 Ba Gua Zhen(dfs && 独立回路 && xor高斯消元)

    题目链接:http://acm.uestc.edu.cn/#/problem/show/1219 题目大意是给了一张图,然后要求一个点通过路径回到这个点,使得xor和最大. 这是CCPC南阳站的一道题 ...

  9. bzoj 2631: tree link-cut-tree

    题目: Description 一棵n个点的树,每个点的初始权值为1.对于这棵树有q个操作,每个操作为以下四种操作之一: + u v c:将u到v的路径上的点的权值都加上自然数c: - u1 v1 u ...

  10. Android HttpGet和HttpPost设置超时

    HttpPost: private Runnable runnable = new Runnable() { @Override public void run() { String url = Ba ...