[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
只不过是一个串,而不是一堆串,因此就可以把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)的更多相关文章
- 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 ——(自动机+DP)
这题由于是一个单词,其实直接kmp+dp也无妨.建立自动机当然也是可以的.设dp[i][j]表示匹配到第i个字母的时候,在单词中处于第j个位置的概率,因此最终的答案是dp[0~m][len],m是输入 ...
- 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/ ...
- ●HDU 3689 Infinite monkey theorem
题链: http://acm.hdu.edu.cn/showproblem.php?pid=3689题解: KMP,概率dp (字符串都从1位置开始) 首先对模式串S建立next数组. 定义dp[i] ...
- [AC自己主动机+可能性dp] hdu 3689 Infinite monkey theorem
意甲冠军: 给n快报,和m频率. 然后进入n字母出现的概率 然后给目标字符串str 然后问m概率倍的目标字符串是敲数量. 思维: AC自己主动机+可能性dp简单的问题. 首先建立trie图,然后就是状 ...
- 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 ...
- HUD3689 Infinite monkey theorem
Infinite monkey theorem Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/ ...
- HDU 4405:Aeroplane chess(概率DP入门)
http://acm.split.hdu.edu.cn/showproblem.php?pid=4405 Aeroplane chess Problem Description Hzz loves ...
随机推荐
- ubuntu12.04+hadoop2.2.0+zookeeper3.4.5+hbase0.96.2+hive0.13.1伪分布式环境部署
目录: 一.hadoop2.2.0.zookeeper3.4.5.hbase0.96.2.hive0.13.1都是什么? 二.这些软件在哪里下载? 三.如何安装 1.安装JDK 2.用parallel ...
- Android 广播大全 Intent Action 事件
Intent.ACTION_AIRPLANE_MODE_CHANGED; //关闭或打开飞行模式时的广播 Intent.ACTION_BATTERY_CHANGED; //充电状态,或者电池的电量发生 ...
- jQuery Mobile_表单元素
<!doctype html> <html> <head> <meta charset="utf-8"> <title> ...
- 转载:使用sklearn做单机特征工程
目录 1 特征工程是什么?2 数据预处理 2.1 无量纲化 2.1.1 标准化 2.1.2 区间缩放法 2.1.3 标准化与归一化的区别 2.2 对定量特征二值化 2.3 对定性特征哑编码 2.4 缺 ...
- selenium+python自动化之元素定位
自动化按步骤拆分的话,可以分为四步操作:定位元素,操作元素,获取返回结果,断言(返回结果与期望结果是否一致),最后自动出测试报告.本篇接下来讲基本的八种元素定位方法.说的通俗一点,就是教大家找对象. ...
- MySQL5.7.13源码编译安装指南(转)
系统 CenterOs 6.5 1.安装依赖包(cmake make gcc等,其实好多都有了,不需要更新,为了防止世界被破坏,就装下) yum install gcc gcc-c++ -yyum i ...
- NFC会员管理-转载自http://technews.cn/2014/09/13/nfc-sticker/
基隆的百年名店“李鹄饼店”误用馊水油,客人纷纷上门退货,因退货条件宽松,客人一货两退,造成巨大的损失.为了平息客人的愤怒,店家允许客人凭发 票或商品办理退货,有的客人先用发票退一次钱,再用商品退一次钱 ...
- TP框架基础
什么是TP框架: 一堆代码的集合,里边有变量.函数.类.常量,设计模式MVC.AR数据库.单例等等.全称是Tinkphp框架; 为什么使用框架: 使用框架将全部精力集中在业务层次,节省50-60%的工 ...
- scala pattern matching
scala语言的一大重要特性之一就是模式匹配.在我看来,这个怎么看都很像java语言中的switch语句,但是,这个仅仅只是像(因为有case关键字),他们毕竟是不同的东西,switch在java中, ...
- 程序员书单_java web编程篇
李兴华JavaWeb开发实战经典 http://download.csdn.net/detail/shenzhq1980/9137653 Servlet与JSP核心编程 第2版_1 http://do ...