[AC自动机+概率dp] hdu 3689 Infinite monkey theorem
来源:互联网 发布:2016开淘宝店卖什么 编辑:程序博客网 时间:2024/05/29 16:11
题意:
给n个字母,和m次数。
然后输入n个字母出现的概率
然后再给一个目标串str
然后问m次中敲出目标串的概率是多少。
思路:
AC自动机+概率dp的简单题。
首先建立trie图,然后就是状态转移了
dp版本:
dp三重循环变量次数,节点数,和字母数
代码:
#include"cstdlib"#include"cstdio"#include"cstring"#include"cmath"#include"queue"#include"algorithm"#include"iostream"#include"map"#include"string"using namespace std;int triecont;double dp[1234][22];struct trie{ int mark,id; trie *next[27],*fail; trie() { mark=id=0; memset(next,0,sizeof(next)); fail=NULL; }};trie *root,*node[22];void init(char *v){ trie *p=root; for(int i=0;v[i];i++) { int tep=v[i]-'a'; if(p->next[tep]==NULL) { p->next[tep]=new trie(); node[triecont]=p->next[tep]; p->next[tep]->id=triecont++; } p=p->next[tep]; } p->mark++;}void getac(){ queue<trie*>q; q.push(root); while(!q.empty()) { trie *p=q.front(); q.pop(); for(int i=0;i<26;i++) { if(p->next[i]==NULL) { if(p==root) p->next[i]=root; else p->next[i]=p->fail->next[i]; } else { if(p==root) p->next[i]->fail=root; else p->next[i]->fail=p->fail->next[i]; q.push(p->next[i]); } } }}int main(){ int n,m; while(scanf("%d%d",&n,&m),(n+m)) { double gl[27]; memset(gl,0,sizeof(gl)); memset(node,0,sizeof(node)); while(n--) { char x[2]; double y; scanf("%s%lf",x,&y); gl[x[0]-'a']=y; } char fuck[27]; scanf("%s",fuck); triecont=0; root=new trie(); node[triecont]=root; root->id=triecont++; init(fuck); getac(); memset(dp,0,sizeof(dp)); dp[0][0]=1; for(int i=1;i<=m;i++) { for(int j=0;j<triecont-1;j++) { for(int k=0;k<26;k++) { trie *p=node[j]->next[k]; dp[i][p->id]+=dp[i-1][j]*gl[k]; } } } double ans=0; for(int i=0;i<=m;i++) ans+=dp[i][triecont-1]; printf("%.2f%%\n",ans*100); } return 0;}
建立可达矩阵版本:
注意到达目标状态 那么他之后的状态的概率就都是1了
然后用快速幂加速~
#include"cstdlib"#include"cstdio"#include"cstring"#include"cmath"#include"queue"#include"algorithm"#include"iostream"using namespace std;int triecont;struct trie{ int mark,id; trie *next[27]; trie *fail; trie() { mark=id=0; memset(next,0,sizeof(next)); fail=NULL; }};struct matrix{ double mat[20][20];};trie *root;void init(char *v){ trie *p=root; for(int i=0; v[i]; i++) { int tep=v[i]-'a'; if(p->next[tep]==NULL) { p->next[tep]=new trie(); p->next[tep]->id=triecont++; } p=p->next[tep]; } p->mark=1;}void getac(){ queue<trie*>q; q.push(root); while(!q.empty()) { trie *p; p=q.front(); q.pop(); for(int i=0; i<26; i++) { if(p->next[i]==NULL) { if(p==root) p->next[i]=root; else p->next[i]=p->fail->next[i]; } else { if(p==root) p->next[i]->fail=root; else p->next[i]->fail=p->fail->next[i]; q.push(p->next[i]); } } }}matrix matmul(matrix a,matrix b,int n){ int i,j,k; matrix c; memset(c.mat,0,sizeof(c.mat)); for(i=0; i<n; i++) { for(j=0; j<n; j++) { for(k=0; k<n; k++) { c.mat[i][j]+=a.mat[i][k]*b.mat[k][j]; } } } return c;}matrix matpow(matrix a,int k,int n){ matrix b; int i; memset(b.mat,0,sizeof(b.mat)); for(i=0; i<n; i++) b.mat[i][i]=1; while(k) { if(k&1) b=matmul(a,b,n); a=matmul(a,a,n); k>>=1; } return b;}int main(){ int n,m; while(scanf("%d%d",&n,&m),(n+m)) { double gl[27]; memset(gl,0,sizeof(gl)); while(n--) { char x[2]; double y; scanf("%s%lf",x,&y); gl[x[0]-'a']+=y; } triecont=0; root=new trie(); root->id=triecont++; char x[12]; scanf("%s",x); init(x); getac(); queue<trie*>q; q.push(root); int used[12]; memset(used,0,sizeof(used)); matrix a,ans; memset(a.mat,0,sizeof(a.mat)); while(!q.empty()) { trie *p=q.front(); q.pop(); if(used[p->id]) continue; used[p->id]=1; if(p->mark==1) //目标状态 后续状态都是本身 { a.mat[p->id][p->id]=1; continue; } for(int i=0;i<26;i++) { if(used[p->next[i]->id]==0) q.push(p->next[i]); a.mat[p->id][p->next[i]->id]+=gl[i]; } } /*for(int i=0;i<triecont;i++) { for(int j=0;j<triecont;j++) printf("%.2f ",a.mat[i][j]); puts(""); }*/ ans=matpow(a,m,triecont); printf("%.2f%%\n",ans.mat[0][triecont-1]*100); } return 0;}
0 0
- [AC自动机+概率dp] hdu 3689 Infinite monkey theorem
- HDU 3689 Infinite monkey theorem (uva11468)ac自动机+dp
- 【AC自动机+DP】 hdu3689 Infinite monkey theorem
- HDU 3689 Infinite monkey theorem (KMP + 概率DP)
- 【hdu 3689】Infinite monkey theorem(概率dp+kmp)
- hdu 3689 Infinite monkey theorem dp
- 【DP】 HDU 3689 Infinite monkey theorem 预处理
- hdu 3689 Infinite monkey theorem
- HDU 3689 Infinite monkey theorem
- hdu 3689 Infinite monkey theorem
- HDU 3689 Infinite monkey theorem(KMP + DP)
- 【hdu3689】 Infinite monkey theorem
- Infinite monkey theorem
- Uva11468 AC自动机+概率dp
- UVA 11468-Substring(AC自动机+概率dp)
- UVA 11468 Substring(AC自动机+概率DP)
- UVa 11468 Substring AC自动机+概率DP
- UVA 11468 Substring AC自动机+概率DP
- maven依赖的插件
- hibernate3 查询表 返回list集合
- 链表反转
- Construct Binary Tree from Preorder and Inorder Traversal
- Sublime Text 2 介紹
- [AC自动机+概率dp] hdu 3689 Infinite monkey theorem
- ubuntu /etc/profile文件
- perl chop和chomp函数
- Machine Learning Foundations q15
- iOS-UICollectionView的使用简介
- apk反编译查看*.java,AndroidManifest.xml,布局xml文件
- 【C++】typedef与define的思考
- C# 6.0 (C# vNext) 新功能之:Expression Bodied Functions and Properties
- 大数据量索引分析