HDU3689 Infinite monkey theorem 无限猴子(字符串DP+KMP)
题目描述:
大概的意思就是根据无限猴子定理,无限只猴子坐在打字机旁瞎敲,总有一个能敲出莎士比亚文集。现在给你一个打字机和一只猴子,打字机的每个按钮(共n个)上的字母及猴子按下这个按钮的概率已知,而且猴子只能按m下按钮,又给定一个串,问猴子打出的乱码中含这个串的概率。
其中n<=26,m<=1000,多组数据,以n=0,m=0结束。以百分数形式输出,保留小数点后2位。
样例:
输入:
4 10
w 0.25
o 0.25
r 0.25
d 0.25
word
2 10
a 1.0
b 0.0
abc
2 100
a 0.312345
b 0.687655
abab
0 0
输出:
2.73%
0.00%
98.54%
解题思路:
对于第一组数据(work)
很显然算法是:0.25*0.25*0.25*0.25*7*100%=2.73%;
而对于第三组(abab)就不成立了,为什么呢?
显然是因为第一组没有重复的字母出现,也就是说,如果你的猴子恰好打下了aba,然后它又不幸地打下了a那么也不算太糟,至少你只需要再打一个bab就可以完成任务了。而对于第一只猴子就没有那么幸运了,如果它打下了wor又不幸地打下了r,那么它必须再打下work才能完成任务。
也就是说,即使你打下了错误的字母,你也有可能创造了一个前缀。
所以说我们只需要求出一个错误的字符创造出的前缀是谁,就可以更新这个前缀出现的概率了。
那么考虑用dp[i][j]表示在猴子打下第i个字母时字符串完成到j的匹配的概率。
而这个由错误创造的前缀是谁,这是不是KMP。
然而这和普通的KMP不一样,或者我学了假的KMP,这次kmp的next数组存的是这个模式串第i位的值对应存在的前缀的位置,也就是说,这次是成功指针,而非失配指针。
dp方程就出来了:dp[这一次敲击][最长匹配的新字符最长前缀]=∑dp[上一次敲击][最长匹配](枚举新字符是谁,再进行前缀操作)
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int n,m;
int l;
bool JDr_is_Handsome=true;
char cmd[];
char a[];
int op[];
int nxt[];
double p[];
double dp[][];
int main()
{
while(JDr_is_Handsome)
{
scanf("%d%d",&n,&m);
if(!n&&!m)
return ;
memset(dp,,sizeof(dp));
memset(p,,sizeof(p));
for(int i=;i<=n;i++)
{
scanf("%s",cmd+);
op[i]=cmd[];
scanf("%lf",&p[i]);
}
scanf("%s",a+);
l=strlen(a+);
nxt[]=;
for(int i=,j=;i<=l;)
{
while(j&&a[j+]!=a[i])j=nxt[j];
if(a[j+]==a[i])j++;
nxt[i]=j;
i++;
}
dp[][]=1.00;
for(int i=;i<=m;i++)
{
for(int j=;j<l;j++)
{
for(int k=;k<=n;k++)
{
int pos=j;
while(pos&&a[pos+]!=op[k])
pos=nxt[pos];
if(a[pos+]==op[k])pos++;
dp[i][pos]+=dp[i-][j]*p[k];
}
}
}
double ans=;
for(int i=l;i<=m;i++)
ans+=dp[i][l];
printf("%.2lf%%\n",ans*100.00);
}
return ;
}
HDU3689 Infinite monkey theorem 无限猴子(字符串DP+KMP)的更多相关文章
- hdu-3689 Infinite monkey theorem 概率dp+kmp
有一只猴子随机敲键盘,给出它可能敲的键以及敲各个键的概率. 输入:n,表示有多少个键,m,表示猴子会敲m次键 n个二元组(字母,数字) 表示键代表的字母及其被敲的概率. 最后一个目标字符串. 问这只猴 ...
- 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 杭州 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+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
Infinite monkey theorem Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/ ...
- HUD3689 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 ——(自动机+DP)
这题由于是一个单词,其实直接kmp+dp也无妨.建立自动机当然也是可以的.设dp[i][j]表示匹配到第i个字母的时候,在单词中处于第j个位置的概率,因此最终的答案是dp[0~m][len],m是输入 ...
随机推荐
- AngularJS初接触
todo.json [ { "action": "Buy Flowers", "done": false }, { "action ...
- java读取jpg图片旋转按比例缩放
//入口 public static BufferedImage constructHeatWheelView(int pageWidth, int pageHeight, DoubleHolder ...
- Object和其他类型的转换
Object对象是一切类的父类(基类),只要是Object对象,可以强制转换为其他类型.
- c#时间差高精度检查
两个时间差的高精度检查 static void Main(string[] args) { Console.WriteLine("开始时间:" + DateTime.Now.ToS ...
- while my time-- , will the meaning++?
// while my time--,will the meaning++? // However,what's the meaning of life ? while(tomorrow>0){ ...
- Django_视图操作
- 常用Linux命令 mount df dd
mount -t tmpfs tmpfs ~/build -o size=1G -t 对应的是类型 -o 对应的是选项 tmpfs是Linux/Unix系统上的一种基于内存的文件系统.tmpfs可以使 ...
- Cocos2d-x--iOS平台lua加密成luac资源方法和Jsc文件<MAC平台开发试用--windows平台暂未研究>
首先要说.近期真的是太忙了.好久没写博客了,今天正好有空,就写一下近期在写游戏中的一些发现: 话说,基于Cocos2dx 引擎 + 脚本写游戏,至今的感触就是能够进行增量更新和即时编译 ...
- Json数据的序列化与反序列化的三种经常用法介绍
下面内容是本作者从官网中看对应的教程后所做的demo.其体现了作者对相关知识点的个人理解..作者才疏学浅,难免会有理解不到位的地方.. 还请各位读者批判性对待... 本文主要介绍在Json数据的序列化 ...
- ifup&&ifdown --- 激活/关闭指定的网络接口。
ifup命令用于激活指定的网络接口. ifup eth0 #激活eth0 ifdown命令用于禁用指定的网络接口. ifdown eth0 #禁用eth0