Question:
Give n letters and m times.
Then enter the probability of N letters
Then, return the target string Str.
Then, I asked how many values the probability of hitting the target string in m times is.
Ideas:
A simple question about AC automation + probability DP.
First, create a trie graph, and then the status is changed.
DP version:
DP triple cycle variable count, node count, and letter count
Code:
#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;}
Build an accessible matrix version:
Note that the probability of reaching the target State is 1.
And then use the fast power to accelerate ~
#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;}
[AC + probability DP] HDU 3689 infinite monkey theorem