HDU 3689 Infinite monkey theorem ——(自动机+DP)
这题由于是一个单词,其实直接kmp+dp也无妨。建立自动机当然也是可以的。设dp[i][j]表示匹配到第i个字母的时候,在单词中处于第j个位置的概率,因此最终的答案是dp[0~m][len],m是输入的长度,len是单词的长度。转移方程见代码,即在一个节点的位置时,枚举下一步的走法,乘以这种走法的概率即是对下一个状态的概率贡献。
其实自动机的fail指针跳转的位置即是kmp中nxt数组跳转的位置。
代码如下:
- {
- while(j && word[j+] != word[i]) j = nxt[j];
- if(word[j+] == word[i]) j++;
- nxt[i] = j;
- }
- }
- int main()
- {
- while(scanf("%d%d",&n,&m) == )
- {
- if(n== && m==) break;
- char s[];
- for(int i=;i<=n;i++)
- {
- scanf("%s%lf",s,p+i);
- c[i] = s[];
- }
- scanf("%s",word+);
- len = strlen(word+);
- get_nxt();
- memset(dp,,sizeof dp);
- dp[][] = 1.0;
- for(int i=;i<m;i++)
- {
- for(int j=;j<len;j++)
- {
- for(int k=;k<=n;k++)
- {
- int pos = j;
- while(pos && word[pos+] != c[k]) pos = nxt[pos];
- if(word[pos+] == c[k]) pos++;
- dp[i+][pos] += dp[i][j] * p[k];
- }
- }
- }
- double ans = 0.0;
- for(int i=;i<=m;i++) ans += dp[i][len];
- printf("%.2f%%\n",ans*100.0);
- }
- return ;
- }
kmp+dp
- #include <bits/stdc++.h>
- using namespace std;
- const int MAX_Tot = + ;
- int n,m,len;
- double p[];
- char word[];
- int nxt[];
- double dp[][];
- struct Aho
- {
- struct state
- {
- int nxt[];
- int fail,cnt;
- }stateTable[MAX_Tot];
- int size;
- queue<int> que;
- void init()
- {
- while(que.size()) que.pop();
- for(int i=;i<MAX_Tot;i++)
- {
- memset(stateTable[i].nxt,,sizeof(stateTable[i].nxt));
- stateTable[i].fail = stateTable[i].cnt = ;
- }
- size = ;
- }
- void insert(char *s)
- {
- int n = strlen(s);
- int now = ;
- for(int i=;i<n;i++)
- {
- char c = s[i];
- if(!stateTable[now].nxt[c-'a'])
- stateTable[now].nxt[c-'a'] = size++;
- now = stateTable[now].nxt[c-'a'];
- }
- stateTable[now].cnt++;
- }
- void build()
- {
- stateTable[].fail = -;
- que.push();
- while(que.size())
- {
- int u = que.front();que.pop();
- for(int i=;i<;i++)
- {
- if(stateTable[u].nxt[i])
- {
- if(u == ) stateTable[stateTable[u].nxt[i]].fail = ;
- else
- {
- int v = stateTable[u].fail;
- while(v != -)
- {
- if(stateTable[v].nxt[i])
- {
- stateTable[stateTable[u].nxt[i]].fail = stateTable[v].nxt[i];
- break;
- }
- v = stateTable[v].fail;
- }
- if(v == -) stateTable[stateTable[u].nxt[i]].fail = ;
- }
- que.push(stateTable[u].nxt[i]);
- }
- /*****建立自动机nxt指针*****/
- else
- {
- if(u == ) stateTable[u].nxt[i] = ;
- else
- {
- int p = stateTable[u].fail;
- while(p != - && stateTable[p].nxt[i] == ) p = stateTable[p].fail;
- if(p == -) stateTable[u].nxt[i] = ;
- else stateTable[u].nxt[i] = stateTable[p].nxt[i];
- }
- }
- /*****建立自动机nxt指针*****/
- }
- }
- }
- }aho;
- int main()
- {
- while(scanf("%d%d",&n,&m) == )
- {
- if(n== && m==) break;
- aho.init();
- char s[];
- memset(p,,sizeof p);
- for(int i=;i<=n;i++)
- {
- double t;
- scanf("%s%lf",s,&t);
- p[s[]-'a'] = t;
- }
- scanf("%s",word+);
- aho.insert(word+); aho.build();
- memset(dp,,sizeof dp);
- dp[][] = 1.0;
- int sz = aho.size-;
- for(int i=;i<m;i++)
- {
- for(int j=;j<sz;j++)
- {
- for(int k=;k<;k++)
- {
- int v = aho.stateTable[j].nxt[k];
- dp[i+][v] += dp[i][j] * p[k];
- }
- }
- }
- double ans = 0.0;
- for(int i=;i<=m;i++) ans += dp[i][sz];
- printf("%.2f%%\n",ans*100.0);
- }
- return ;
- }
自动机+dp
HDU 3689 Infinite monkey theorem ——(自动机+DP)的更多相关文章
- HDU 3689 Infinite monkey theorem(DP+trie+自动机)(2010 Asia Hangzhou Regional Contest)
Description Could you imaging a monkey writing computer programs? Surely monkeys are smart among ani ...
- 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 (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 3689 杭州 10 现场 J - Infinite monkey theorem 概率dp kmp 难度:1
J - Infinite monkey theorem Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d &am ...
- hdu-3689 Infinite monkey theorem 概率dp+kmp
有一只猴子随机敲键盘,给出它可能敲的键以及敲各个键的概率. 输入:n,表示有多少个键,m,表示猴子会敲m次键 n个二元组(字母,数字) 表示键代表的字母及其被敲的概率. 最后一个目标字符串. 问这只猴 ...
- HUD3689 Infinite monkey theorem
Infinite monkey theorem Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/ ...
随机推荐
- 轻松搭建CAS 5.x系列(2)-搭建HTTPS的SSO SERVER端
概要说明 CAS要求,必须使用HTTPS的服务,否则就只等实现登录,无法实现单点登录.科普下HTTPS,网站有HTTP和HTTPS两种协议.HTTP是浏览器到网站之间是明文传输,比如你输入帐号名和密码 ...
- regex 正则分割字符串
string _content=adak.sjdkajskj爱25教:师的656教案时; string en=@"\.|56|25";//单个[asj]分别以a,s,j为分隔符. ...
- c++容易混淆知识点
C ++令人困惑的知识点1 函数传递指针和传递引用之间的区别? 1 GT;指针定义可能未初始化,但引用不可能; 2 - ;引用只能与一个实体组合,指针可以与多个实体组合; 3 GT;加法和减法的含义是 ...
- JavaScript特点有哪些
JavaScript特点有哪些 JavaScript 文字脚本语言是一种动态的.弱类型的.基于原型的语言,具有内置的支持类型.它的解释器被称为javascript引擎,是浏览器的一部分,广泛用于客户端 ...
- python 判断两个ip地址是否属于同一子网
python 判断两个ip地址是否属于同一子网 """ 判断两个IP是否属于同一子网, 需要判断网络地址是否相同 网络地址:IP地址的二进制与子网掩码的二进制地址逻辑&q ...
- json-server
json-server 一个前端模拟数据的本地化服务器 安装 npm install -g json-server 查看是否安装成功 json-server -v 新建一个文件夹 在文件夹中新建db. ...
- 《浏览器工作原理与实践》<07>变量提升:JavaScript代码是按顺序执行的吗?
讲解完宏观视角下的浏览器后,从这篇文章开始,我们就进入下一个新的模块了,这里我会对 JavaScript 执行原理做深入介绍. 今天在该模块的第一篇文章,我们主要讲解执行上下文相关的内容.那为什么先讲 ...
- Matlab---绘图及其位置摆放
Matlab---绘图及其位置摆放 [@WP@20180509] 一.绘图函数 (1)绘制二维图形 (1.1) plot( ) 函数的应用格式. 1,plot(x). 当x 为一向量时,以x 元素的值 ...
- 【转】GO语言map类型interface{}转换踩坑小记
原文:https://www.az1314.cn/art/69 ------------------------------------------ mapA := make([string]inte ...
- sqlite3.OperationalError: no such table: account_user
你可能是在项目中安装了多个app, 首先删除相关app的migration文件中的子文件 执行建表的时候使用: python manage.py makemigrations appname pyth ...