HDU 3689 Infinite monkey theorem(DP+trie+自动机)(2010 Asia Hangzhou Regional Contest)
Description
Input
Output
题目大意:有n个字母,每个字母有一个敲击概率,敲m次,问敲m次之后的串包含给出子串的概率是多少。
思路:对子串建立一个trie树,建一个自动机(像我这种懒得想的人会先建出一个AC自动机),得出每个点走一步到达的位置。然后DP,dp[m][x]为第m步走到第x个点的概率,最后把dp[m][x]加起来,再拿1-sum就是答案了。
PS:其实我觉得直接KMP也可以……反正给出的串很短……
代码(0MS):
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std; struct Node {
Node *go[], *fail;
int id;
Node(int i = ) {
id = i;
memset(go, , sizeof(go));
fail = ;
}
}; void build(Node *root, char *str) {
Node *p = root;
for(int i = ; str[i]; ++i) {
int index = str[i] - 'a';
if(!p->go[index]) p->go[index] = new Node(i + );
p = p->go[index];
}
} void makeFail(Node *root) {
queue<Node*> que; que.push(root);
while(!que.empty()) {
Node *tmp = que.front(); que.pop();
for(int i = ; i < ; ++i) {
if(!tmp->go[i]) continue;
if(tmp == root) tmp->go[i]->fail = root;
else {
Node *p = tmp->fail;
while(p) {
if(p->go[i]) {
tmp->go[i]->fail = p->go[i];
break;
}
p = p->fail;
}
if(!p) tmp->go[i]->fail = root;
}
que.push(tmp->go[i]);
}
}
root->fail = root;
} void makeGo(Node *root, char *str) {
Node *tmp = root;
for(int i = ; i < ; ++i)
if(i != str[] - 'a') root->go[i] = root;
for(int i = ; str[i]; ++i) {
int index = str[i] - 'a';
tmp = tmp->go[index];
for(int j = ; j < ; ++j) {
Node *p = tmp;
while(true) {
if(p->go[j]) {
tmp->go[j] = p->go[j];
break;
}
p = p->fail;
if(p == root) break;
}
if(p == root) tmp->go[j] = root->go[j];
}
}
} int n, m;
char s[];
double dp[][];
double pro[]; double solve(Node *root) {
int cur = , len = strlen(s);
dp[cur][] = ;
for(int i = ; i <= len; ++i) dp[cur][i] = ;
for(int t = ; t < m; ++t) {
for(int i = ; i <= len; ++i) dp[cur ^ ][i] = ;
for(int i = ; i < ; ++i)
dp[cur ^ ][root->go[i]->id] += pro[i] * dp[cur][];
Node *tmp = root;
for(int i = ; i < len - ; ++i) {
int index = s[i] - 'a';
tmp = tmp->go[index];
for(int j = ; j < ; ++j)
dp[cur ^ ][tmp->go[j]->id] += pro[j] * dp[cur][i + ];
}
cur ^= ;
//for(int i = 0; i <= len; ++i) printf("%.6f ", dp[cur][i]); printf("\n");
}
double ret = ;
for(int i = ; i < len; ++i) {
ret += dp[cur][i];
}
return - ret;
} int main() {
while(scanf("%d%d", &n, &m) != EOF) {
if(n == && m == ) break;
char c; double x;
for(int i = ; i < ; ++i) pro[i] = ;
for(int i = ; i < n; ++i)
scanf(" %c%lf", &c, &x), pro[c - 'a'] = x;
scanf("%s", s);
Node *root = new Node;
build(root, s);
makeFail(root);
makeGo(root, s);
printf("%.2f%%\n", solve(root) * );
}
}
HDU 3689 Infinite monkey theorem(DP+trie+自动机)(2010 Asia Hangzhou Regional Contest)的更多相关文章
- HDU 3689 Infinite monkey theorem [KMP DP]
Infinite monkey theorem Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Oth ...
- hdu 3689 Infinite monkey theorem
Infinite monkey theorem Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/ ...
- HDU 3689 Infinite monkey theorem ——(自动机+DP)
这题由于是一个单词,其实直接kmp+dp也无妨.建立自动机当然也是可以的.设dp[i][j]表示匹配到第i个字母的时候,在单词中处于第j个位置的概率,因此最终的答案是dp[0~m][len],m是输入 ...
- [HDU 3689]Infinite monkey theorem (KMP+概率DP)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3689 黄老师说得对,题目只有做wa了才会有收获,才会有提高. 题意:一个猴子敲键盘,键盘上有n个键,猴 ...
- [AC自己主动机+可能性dp] hdu 3689 Infinite monkey theorem
意甲冠军: 给n快报,和m频率. 然后进入n字母出现的概率 然后给目标字符串str 然后问m概率倍的目标字符串是敲数量. 思维: AC自己主动机+可能性dp简单的问题. 首先建立trie图,然后就是状 ...
- ●HDU 3689 Infinite monkey theorem
题链: http://acm.hdu.edu.cn/showproblem.php?pid=3689题解: KMP,概率dp (字符串都从1位置开始) 首先对模式串S建立next数组. 定义dp[i] ...
- HDU 3696 Farm Game(拓扑+DP)(2010 Asia Fuzhou Regional Contest)
Description “Farm Game” is one of the most popular games in online community. In the community each ...
- HDU 3685 Rotational Painting(多边形质心+凸包)(2010 Asia Hangzhou Regional Contest)
Problem Description Josh Lyman is a gifted painter. One of his great works is a glass painting. He c ...
- HDU 3686 Traffic Real Time Query System(双连通分量缩点+LCA)(2010 Asia Hangzhou Regional Contest)
Problem Description City C is really a nightmare of all drivers for its traffic jams. To solve the t ...
随机推荐
- JS JavaScript中的this
this是JavaScript语言中的一个关键字 它是函数运行时,在函数体内部自动生成的一个对象,只能在函数体内部使用. function test() { this.x = 1; } 上面代码中,函 ...
- SpringBoot非官方教程 | 第十一篇:springboot集成swagger2,构建优雅的Restful API
转载请标明出处: 原文首发于:https://www.fangzhipeng.com/springboot/2017/07/11/springboot-swagger2/ 本文出自方志朋的博客 swa ...
- SpringBoot非官方教程 | 第六篇:springboot整合mybatis
转载请标明出处: 原文首发于:https://www.fangzhipeng.com/springboot/2017/07/11/springboot-mybatis/ 本文出自方志朋的博客 本文主要 ...
- selenium之Xpath定位
1. 绝对定位: driver.find_element_by_xpath("/html/body/div[x]/form/input") x 代表第x个 div标签,注意,索引从 ...
- spring入门(五) spring mvc+hibernate
核心是让SessionFactory由Spring管理 1.引入依赖 <!-- https://mvnrepository.com/artifact/org.springframework/sp ...
- ETO的公开赛T1《矿脉开采》题解(另类版)
这道题别看是签到题,写起来一点不简单 出题人的正解是双向搜索 我们把物品分成两半 每一半分别跑搜索 答案存下来,用个双指针合并即可 然后我构造了两组数据卡掉了他,不得不缩小数据范围 但我这里为什么要致 ...
- Sql Server 查看存储过程最后修改时间
Sql Server 查看存储过程最后修改时间 select * from sys.procedures order by modify_date desc
- CentOS7下rsync服务的基本详解和使用
第1章 Rsync基本概述 1.1 什么是Rsync rsync是一款开源,快速,多功能的可实现增量的本地或远程的数据镜像同步备份的优秀工具.适用于多个平台.从软件名称可以看出来是远程同步的意思(re ...
- Python 一些好玩的函数
一.匿名函数 什么匿名是函数: 不需要使用def函数名的函数或者子程序 函数语法: lambda 参数:表达式 函数特点: 1.lambda只是一个表达式,省去定义函数过程,让代码更精简 2.lamb ...
- Python的virtualenv你用过吗?
1. 为什么要有virtualenv 在使用 Python 开发的过程中,工程一多,难免会碰到不同的工程依赖不同版本的库的问题: 亦或者是在开发过程中不想让物理环境里充斥各种各样的库,引发未来的依赖灾 ...