HDU 3689 Infinite monkey theorem [KMP DP]

Infinite monkey theorem

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1702 Accepted Submission(s):
882

Problem Description

Could you imaging a monkey writing computer programs?
Surely monkeys are smart among animals. But their limited intelligence is no
match for our human beings. However, there is a theorem about monkeys, and it
states that monkeys can write everything if given enough time.
The theorem is
called “Infinite monkey theorem”. It states that a monkey hitting keys at random
on a typewriter keyboard for an infinite amount of time will almost surely type
any given text, which of course includes the programs you are about to write
(All computer programs can be represented as text, right?).
It’s very easy to
prove this theorem. A little calculation will show you that if the monkey types
for an infinite length of time the probability that the output contains a given
text will approach 100%.
However, the time used is too long to be physically
reasonable. The monkey will not be able to produce any useful programs even if
it types until the death of the universe. To verify this and ensure that our
human beings are not replaceable by monkeys, you are to calculate the
probability that a monkey will get things right.

Input

There will be several test cases.
Each test case
begins with a line containing two integers n and m separated by a whitespace
(2<=n<=26, 1<=m<=1000). n is the number of keys on the typewriter
and the monkey will hit these keys m times. Thus the typewriter will finally
produce an output of m characters.
The following n lines describe keys on the
typewriter. Each line has a lower case letter and a real number separated by a
whitespace. The letter indicates what the typewriter will produce if the monkey
hits that key and the real number indicates the probability that the monkey will
hit this key. Two hits of the monkey are independent of each other (Two
different hits have the same probability for a same key), and sum of all the
probabilities for each key is ensured to be 1.
The last line of the test case
contains a word composed of lower case letters. The length of the word will be
less than or equal to 10.
The input will end with a line of two zeros
separated by a whitespace. This line should not be processed.

Output

For each test case, output one line containing the
probability that the given word will appear in the typewriter’s output. The
output should be in percentage format and numbers should be rounded to two
digits after the decimal point.

Source

2010
Asia Hangzhou Regional Contest


题意:

字符集中有一些字符(最多26个),给出每个字符的出现概率(它们的和保证为1)
再给出一个子串B
求:任给一个长度为N的字符串A(只能包含字符集中的字符),使得B是A的子串的概率。


一边生成A,一边用KMP匹配B

f[i][j]表示生成到i位,当前匹配到B的j位的概率

枚举下一个字符,然后用KMP匹配就行了....匹配到now,就是f[i+1][now]+=f[i][j]*p[k]

#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>
using namespace std;
typedef long long ll;
const int N=1005,M=15;
int cn,n,m,fail[N];
char c[2],b[N],key[N];
double p[N],f[N][M];
void getFail(int n,char s[]){
    fail[1]=0;
    for(int i=2;i<=n;i++){
        int j=fail[i-1];
        while(j&&s[j+1]!=s[i]) j=fail[j];
        fail[i]=s[j+1]==s[i]?j+1:0;
    }
}
void dp(){
    memset(f,0,sizeof(f));
    f[0][0]=1;
    for(int i=0;i<n;i++)
        for(int j=0;j<m;j++) if(f[i][j])
            for(int k=1;k<=cn;k++){
                int now=j;
                while(now&&b[now+1]!=key[k]) now=fail[now];
                now+=b[now+1]==key[k];
                f[i+1][now]+=f[i][j]*p[k];
            }
    double ans=0;
    for(int i=1;i<=n;i++) ans+=f[i][m];
    ans*=100;
    printf("%.2lf%%\n",ans);
}
int main(){
    //freopen("in.txt","r",stdin);
    while(scanf("%d%d",&cn,&n)!=EOF&&(cn||n)){
        for(int i=1;i<=cn;i++){
            scanf("%s%lf",c,&p[i]);
            key[i]=c[0];
        }
        scanf("%s",b+1);
        m=strlen(b+1);
        getFail(m,b);
        dp();
    }
}
时间: 2024-10-10 12:54:38

HDU 3689 Infinite monkey theorem [KMP DP]的相关文章

[HDU 3689]Infinite monkey theorem (KMP+概率DP)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3689 黄老师说得对,题目只有做wa了才会有收获,才会有提高. 题意:一个猴子敲键盘,键盘上有n个键,猴子敲第i个键的概率是p[i],问敲m次后形成的字符串里出现给定串的概率是多少. 这实际上就跟那个ac自动机转为trie图然后dp一样的. 类似的题目有POJ 2778,这篇题解不错:http://blog.csdn.net/luyuncheng/article/details/8643001 只不过

HDU 3689 Infinite monkey theorem(KMP + DP)

题目链接:点击打开链接 思路: 用d[i][j]表示前i个字符,已经匹配了字母中的j个字符,最终包含这个字母的概率. 每次转移的时候有n个方向, 表示第i个字符选哪个字符, 那么有个问题, 如果我当前选的这个字符失配了, 那么转移之后我还匹配了多少个字符. 这恰恰是KMP能做的. 细节参见代码: #include <cstdio> #include <cstring> #include <algorithm> #include <iostream> #inc

[AC自动机+概率dp] hdu 3689 Infinite monkey theorem

题意: 给n个字母,和m次数. 然后输入n个字母出现的概率 然后再给一个目标串str 然后问m次中敲出目标串的概率是多少. 思路: AC自动机+概率dp的简单题. 首先建立trie图,然后就是状态转移了 dp版本: dp三重循环变量次数,节点数,和字母数 代码: #include"cstdlib" #include"cstdio" #include"cstring" #include"cmath" #include"

●HDU 3689 Infinite monkey theorem

题链: http://acm.hdu.edu.cn/showproblem.php?pid=3689题解: KMP,概率dp (字符串都从1位置开始) 首先对模式串S建立next数组. 定义dp[i][j]表示猴子打的串长度为i,且该串的后缀与模式串最多匹配到j位置的概率. 显然dp[0][0]=1, 考虑如何转移: 枚举下一个打出的字符为c,然后用kmp的next数组找到模式串中可以继续匹配的位置k. 即:k=j+1; while(k&&S[k]!=c) k=next[k]; 然后将dp

hdu 3689 Infinite monkey theorem

TMD这些神奇的猴子... DP里面用KMP的next的数组来搞一搞,(不是很会,一开始想这样搞,然而思路很乱,就弃疗了,,,DP太虚了) 1 #include<bits/stdc++.h> 2 #define N 1000005 3 #define LL long long 4 #define inf 0x3f3f3f3f 5 using namespace std; 6 inline int ra() 7 { 8 int x=0,f=1; char ch=getchar(); 9 whil

hdu 3689 杭州 10 现场 J - Infinite monkey theorem 概率dp kmp

J - Infinite monkey theorem Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit Status Practice HDU 3689 Appoint description:  System Crawler  (2014-11-09) Description Could you imaging a monkey writing computer progra

HUD3689 Infinite monkey theorem

Infinite monkey theorem Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 1703    Accepted Submission(s): 883 Problem Description Could you imaging a monkey writing computer programs? Surely monke

hdu 3336 Count the string KMP+DP

Count the string Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 6375    Accepted Submission(s): 2947 Problem Description It is well known that AekdyCoin is good at string problems as well as n

HDU 1069 Monkey and Banana(DP 长方体堆放问题)

Monkey and Banana Problem Description A group of researchers are designing an experiment to test the IQ of a monkey. They will hang a banana at the roof of a building, and at the mean time, provide the monkey with some blocks. If the monkey is clever