UVA 11468 Substring(AC自动机 + 记忆化搜索)
来源:互联网 发布:淘宝发票抬头哪里设置 编辑:程序博客网 时间:2024/05/23 02:04
题目链接:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=2463
题意:给定k个模式串,给定n个字母,每个字母均有一个发生概率,给定长度为l,求用给定n个字母构成的长度为l的不包含任何模式串的文本串概率。
思路:利用k个模式串构成Trie,对于每个模式串结尾字母结点,标记为单词结点,求一遍失配边,不同的是,模式串结尾字母结点的失配边所连接的结点应也被标记。从Trie根结点往下走,利用dp[i][j]
表示根结点为i
,剩余j
步的概率,在Trie上记忆化搜索。
#include <stdio.h>#include <iostream>#include <string.h>#include <math.h>#include <queue>#include <vector>using namespace std;const int N = 4e2 + 10;const int SIZE = 70;struct AC { int ch[N][SIZE]; int sz; bool ed[N]; int f[N]; double dp[N][105]; bool vis[N][105]; double p[SIZE]; int newnode() { memset(ch[sz], 0, sizeof(ch[sz])); ed[sz] = false; f[sz] = 0; return sz++; } void init() { sz = 0; for (int i = 0; i < SIZE; i++) p[i] = 0; memset(vis, false, sizeof(vis)); newnode(); } int idx(char c) { if (c >= '0' && c <= '9') return c - '0'; else if (c >= 'a' && c <= 'z') return c - 'a' + 10; else return c - 'A' + 36; } void insert(char *s) { int u = 0; for (int i = 0; s[i]; i++) { int j = idx(s[i]); if (!ch[u][j]) ch[u][j] = newnode(); u = ch[u][j]; } ed[u] = true; } void getfail() { queue<int> q; for (int i = 0; i < SIZE; i++) if (ch[0][i]) q.push(ch[0][i]); while (!q.empty()) { int u = q.front(); q.pop(); for (int i = 0; i < SIZE; i++) { int v = ch[u][i]; if (v) { int r = f[u]; q.push(v); while (r && !ch[r][i]) r = f[r]; f[v] = ch[r][i]; // 单词结点失配边连向的结点也为单词结点 ed[v] |= ed[f[v]]; } else { ch[u][i] = ch[f[u]][i]; } } } } double dfs(int u, int j) { if (j == 0) return 1.0; if (vis[u][j]) return dp[u][j]; vis[u][j] = true; dp[u][j] = 0.0; for (int i = 0; i < SIZE; i++) if (!ed[ch[u][i]]) dp[u][j] += (p[i] * dfs(ch[u][i], j - 1)); return dp[u][j]; }}ac;int main() { int t_case; scanf("%d", &t_case); for (int i_case = 1; i_case <= t_case; i_case++) { int k, n, l; char str[30]; scanf("%d", &k); ac.init(); for (int i = 0; i < k; i++) { scanf("%s", str); ac.insert(str); } ac.getfail(); scanf("%d", &n); for (int i = 0; i < n; i++) { double pi; scanf("%s%lf", str, &pi); ac.p[ac.idx(str[0])] = pi; } scanf("%d", &l); printf("Case #%d: %.6lf\n", i_case, ac.dfs(0, l)); } return 0;}
0 0
- UVA 11468 Substring(AC自动机 + 记忆化搜索)
- uva 11468-Substring ac自动机 + 记忆化搜索
- uva 11468 Substring (ac自动机+记忆化搜索)
- UVa 11468 AC自动机+记忆化搜索
- UVa 11468 substring AC自动机+记忆化搜索+全概率公式
- UVA 11468 Substring(AC自动机 + dp)
- 【UVA】11468-Substring(AC自动机)
- UVA 11468 Substring(AC自动机+dp)
- UVA - 11468 Substring ( AC自动机 + dp)
- uva 1076 - Password Suspects(AC自动机+记忆化搜索)
- UVA 11468 Substring AC自动机
- UVA 11468 - Substring(AC自动机)
- Uva 11468 Substring (AC自动机)
- UVA 11468(Substring-AC自动机上dp)[Template:AC自动机]
- uva1399 - Puzzle AC自动机+记忆化搜索
- AC自动机+记忆化搜索uva1399Puzzle
- UVA11468 AC自动机+记忆化搜索
- UVA 11468 —— Substring(AC自动机+DP)
- 数值优化(Numerical Optimization)学习系列-带约束最优化(Constrained Optimization)
- UVA - 120 Stacks of Flapjacks
- Android Eclipse 快捷键总结
- 第3章 隐藏实现
- ubuntu下简单安装opencv的方法
- UVA 11468 Substring(AC自动机 + 记忆化搜索)
- jquery学习笔记
- SqlHelper类执行数据库
- JAVA日志组件系列(三)log4j+logback+slf4j的关系与调试
- sql server中char nchar nvarchar varchar
- C++ 复习
- 软件工程第二次作业(2)
- 达内学习日志Day29:基础查询
- hdu 1548 A strange lift(BFS)