题目链接: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

只不过是一个串,而不是一堆串,因此就可以把AC自动机换为KMP来搞。

设dp[i][j]表示猴子敲了i次键盘走到状态为j的点上

注意next数组的含义,我开始就是没有理解透彻next数组的意思。

如果说str[i]!=c那么str[next[i]]也一定不是c

代码:

 #include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <map>
#include <iterator>
#include <vector>
using namespace std;
typedef long long LL; int next[],n,m;
char str[];
double f[],dp[][]; void get_next(int m,const char* str){
int j = ;
next[] = ;
for( int i=;i<m;i++ ){
while( j> && str[j+]!=str[i] ) j = next[j];
if( str[j+] == str[i] ) j++;
next[i] = j;
}
} int main(){
while(scanf("%d%d",&n,&m)!=EOF){
if( n==&&m== ) break;
char c[]; double d;
memset(f,,sizeof(f));
vector<int> v;
for(int i=;i<n;i++){
scanf("%s%lf",c,&d);
f[c[]-'a'] = d;
v.push_back(c[]-'a');
}
scanf("%s",str+);
int len = strlen(str+);
memset(next,,sizeof(next));
get_next(len,str);
memset(dp,,sizeof(dp));
dp[][] = ;
for(int i=;i<m;i++){
for(int j=;j<len;j++){
for(int k=;k<v.size();k++){
int fa = j;
while( fa&&v[k]!=str[fa+]-'a' ) fa = next[fa];
if( str[fa+]-'a'==v[k] ) fa++;
dp[i+][fa] += dp[i][j] * f[v[k]];
}
}
}
double sum = ;
for(int i=;i<=m;i++) sum += dp[i][len];
printf("%.2f%%\n",sum);
}
return ;
}

或者说可以用矩阵来实现

 #include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <map>
#include <iterator>
#include <vector>
using namespace std;
typedef long long LL; int next[],n,m;
char str[];
double f[]; void get_next(int m,const char* str){
int j = ;
next[] = ;
for( int i=;i<=m;i++ ){
while( j> && str[j+]!=str[i] ) j = next[j];
if( str[j+] == str[i] ) j++;
next[i] = j;
}
} struct Matrix{
double m[][];
Matrix(){
memset(m,,sizeof(m));
}
Matrix operator*(const Matrix &a){
Matrix res;
for(int i=;i<;i++){
for(int j=;j<;j++){
for(int k=;k<;k++){
res[i][j] += m[i][k] * a[k][j];
}
}
}
return res;
}
Matrix operator*= (const Matrix &a){
return *this = operator*(a);
}
const double* operator[] (size_t idx) const{
return m[idx];
}
double* operator[] (size_t idx) {
return m[idx];
}
}; Matrix pow_bin(Matrix x,int e){
Matrix res;
for(int i=;i<;i++) res.m[i][i] = ;
while( e ){
if( e& ) res *= x;
x*=x;
e>>=;
}
return res;
} int main(){
while(scanf("%d%d",&n,&m)!=EOF){
if( n==&&m== ) break;
char c[]; double d;
vector<int> v;
memset(f,,sizeof(f));
for(int i=;i<n;i++){
scanf("%s%lf",c,&d);
f[c[]-'a'] = d;
v.push_back(c[]-'a');
}
getchar();
gets(str+);
int len = strlen(str+);
get_next(len,str);
Matrix ma;
for(int i=;i<len;i++){
for(int j=;j<v.size();j++){
int fa = i;
while( fa&&str[fa+]-'a'!=v[j] ) fa = next[fa];
if( str[fa+]-'a'==v[j] ) fa++;
ma[i][fa] += f[v[j]];
}
}
Matrix res = pow_bin(ma,m);
double ans = ;
for(int i=;i<len;i++){
ans += res[][i];
}
printf("%.2f%%\n",-ans*);
}
return ;
}

矩阵版本

[HDU 3689]Infinite monkey theorem (KMP+概率DP)的更多相关文章

  1. HDU 3689 Infinite monkey theorem [KMP DP]

    Infinite monkey theorem Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Oth ...

  2. HDU 3689 Infinite monkey theorem ——(自动机+DP)

    这题由于是一个单词,其实直接kmp+dp也无妨.建立自动机当然也是可以的.设dp[i][j]表示匹配到第i个字母的时候,在单词中处于第j个位置的概率,因此最终的答案是dp[0~m][len],m是输入 ...

  3. 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 ...

  4. hdu 3689 Infinite monkey theorem

    Infinite monkey theorem Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/ ...

  5. ●HDU 3689 Infinite monkey theorem

    题链: http://acm.hdu.edu.cn/showproblem.php?pid=3689题解: KMP,概率dp (字符串都从1位置开始) 首先对模式串S建立next数组. 定义dp[i] ...

  6. [AC自己主动机+可能性dp] hdu 3689 Infinite monkey theorem

    意甲冠军: 给n快报,和m频率. 然后进入n字母出现的概率 然后给目标字符串str 然后问m概率倍的目标字符串是敲数量. 思维: AC自己主动机+可能性dp简单的问题. 首先建立trie图,然后就是状 ...

  7. 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 ...

  8. HUD3689 Infinite monkey theorem

    Infinite monkey theorem Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/ ...

  9. HDU 4405:Aeroplane chess(概率DP入门)

    http://acm.split.hdu.edu.cn/showproblem.php?pid=4405 Aeroplane chess Problem Description   Hzz loves ...

随机推荐

  1. JS对日期时间的操作

    代码: //判断是否超期(有效期开始超过一年后算已超期) function IsEffect(effectDate) { var val = ""; var currentDate ...

  2. Linux中的free命令

    解释一下Linux上free命令的输出. 下面是free的运行结果,一共有4行.为了方便说明,我加上了列号.这样可以把free的输出看成一个二维数组FO(Free Output).例如: FO[2][ ...

  3. 如何面试程序员 zhuan zai

    zhuan zai  http://blog.csdn.net/cuibo1123/article/details/41931909aia 面试对于大多数开发人员来说是一项很基本的技能.一次失败的招聘 ...

  4. 阿里云nat mysql配置

    # Generated by iptables-save v1. :: *filter :INPUT DROP [:] :FORWARD ACCEPT [:] :OUTPUT ACCEPT [:] # ...

  5. Eclipse的中文字体设置

    打开eclipse中文字体很小,简直难以辨认.在网上搜索发现这是由于Eclipse 用的字体是 Consolas,显示中文的时候默认太小了.解决方式有两种:一.把字体设置为Courier New  操 ...

  6. LinearLayout属性baselineAligned的作用及baseline

    相信大家对LinearLayout已经相当熟悉,但你们是否了解它的属性baselineAligned呢? Android官方文档是这么描述的:

  7. HTML标签使用特写

    页面定时刷新标签 //页面定时刷新 <meta http-equiv="> Input标记各种特殊用法 <%--禁止鼠标选择内容--%> <input id=& ...

  8. DatagridView 最后编辑状态数据无法自动提交的问题

    DataGridView1.CurrentCell = null 从一个帖子上看的,绝招! http://bbs.csdn.net/topics/120020614

  9. Python处理Excel文档(xlrd, xlwt, xlutils)

    简介 xlrd,xlwt和xlutils是用Python处理Excel文档(*.xls)的高效率工具.其中,xlrd只能读取xls,xlwt只能新建xls(不可以修改),xlutils能将xlrd.B ...

  10. \r\n的坑

    \r回车符 \n换行符 由于历史原因,windows下的换行符为\r\n linux或者html等开源或公开标准的换行符是\n ---- 为什么windows下的回车换行是\r\n? 第一台打印机,每 ...