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/ ...
随机推荐
- CentOS7 mysql支持中文
# vim /etc/my.cnf # For advice on how to change settings please see# http://dev.mysql.com/doc/refman ...
- C# enum枚举知识总结
C#中除了简单的变量类型外,还提供了三种较为复杂的变量类型,包括枚举.结构和数组.本文主要讲述枚举相关的知识. 枚举类型(也称为枚举),提供了一种有效的方式,来定义可能分配给变量的一组已命名的整数常量 ...
- Js setTimeout 用法
setTimeout( ) 是属于 window 的 method, 但我们都是略去 window 这顶层物件名称, 这是用来设定一个时间, 时间到了, 就会执行一个指定的 method. setTi ...
- SQL生成自动序号 带有占位符(掩码),可以调整占位长度的语句
MSSQL 语句 --声明变量 DECLARE @i int DECLARE @xh varchar(10) DECLARE @name varchar(10) Set @i = 0 --开始循环插入 ...
- C# 关键字 virtual、override和new的用法
代码如下: class A { public void foo() { Console.WriteLine("A::foo()"); } public virtual void b ...
- Python与C/C++相互调用(转)
原文链接 作者 一.问题 Python模块和C/C++的动态库间相互调用在实际的应用中会有所涉及,在此作一总结. 二.Python调用C/C++ 1.Python调用C动态链接库 Python调用C库 ...
- liunx pip安装
方法一 wget https://bootstrap.pypa.io/get-pip.py python get-pip.py 方法二 wget https://pypi.python.org/pac ...
- OS 常见函数使用
os.sep:取代操作系统特定的路径分隔符 os.name:指示你正在使用的工作平台.比如对于Windows,它是'nt',而对于Linux/Unix用户,它是'posix'. os.getcwd:得 ...
- scala学习(4)---Array定长数组操作
ScalaArrayNote: https://www.jianshu.com/p/d906f00c05bf
- rac 关于RACScheduler的一点学习
RACScheduler 信号调度器,是一个线性执行队列,rac中的信号可以在RACScheduler上执行任务.发送结果,底层用GCD封装的. rac中提供生成线程的几个方法: 1:schedul ...