标签:sim process 题意 other final depend monk http namespace
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1703 Accepted Submission(s): 883
动态规划+KMP
想象一边随机生成字符串A,一边用KMP匹配字符串B的过程
f[i][j]表示随机生成到第i位,此时B串匹配到第j位的概率
枚举下一位生成字符c,设其生成概率为pc
假设下一位填c,计算出KMP匹配指针j应该移动到now
f[i+1][now] += f[i][j]*pc
已经匹配到第m位的状态不再进行转移
ans = ∑f[i][m]
#include<cstdio> #include<cstring> using namespace std; const int N=1005; int cn,n,m,fail[N]; char B[N],key[30]; double p[30],f[N][N]; void get_fail(){ int p=0;fail[1]=0; for(int i=2;i<=m;i++){ while(p>0&&B[i]!=B[p+1]) p=fail[p]; if(B[i]==B[p+1]) p++; fail[i]=p; } } 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++){ for(int k=1;k<=cn;k++){ int now=j; while(now>0&&key[k]!=B[now+1]) now=fail[now]; if(key[k]==B[now+1]) now++; 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.0; printf("%.2lf%%\n",ans); } int main(){ char s[3]; while(scanf("%d%d",&cn,&n)==2){ if(!cn&&!n) break; for(int i=1;i<=cn;i++){ scanf("%s %lf",s,&p[i]); key[i]=s[0]; } scanf("%s",B+1); m=strlen(B+1); get_fail(); dp(); } return 0; }
HUD3689 Infinite monkey theorem
标签:sim process 题意 other final depend monk http namespace
原文地址:http://www.cnblogs.com/shenben/p/6383166.html