zoukankan      html  css  js  c++  java
  • Infinite monkey theorem(hdu 3689)

    题意:问随机生成一个长度为m(m<=1000)长度的字符串,出现某个子串s的概率是多少。

    /*
      KMP+DP
      设f[i][j]表示A生成到第i位,此时B串匹配到第j位的概率。 
      转移方程为f[i+1][k]+=f[i][j]*lv(枚举的第i位生成字符的概率)
      k位如果第i位生成该字符,那么它能和B串匹配到的地方。 
    */
    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #define N 1010
    using namespace std;
    double lv[30],dp[N][N];
    char s[N],zifu[30];
    int n,m,len,fail[N];
    void get_fail(){
        fail[1]=0;
        for(int i=2;i<=len;i++){
            int p=fail[i-1];
            while(p&&s[p+1]!=s[i]) p=fail[p];
            if(s[p+1]==s[i]) fail[i]=p+1;
            else fail[i]=0;
        }
    }
    void work(){
        for(int i=1;i<=n;i++){
            char c;cin>>zifu[i];
            scanf("%lf",&lv[i]);
        }
        scanf("%s",s+1);len=strlen(s+1);
        get_fail();
        dp[0][0]=100.0;
        for(int i=0;i<m;i++)
            for(int j=0;j<len;j++)
                for(int k=1;k<=n;k++){
                    int p=j;
                    while(p&&s[p+1]!=zifu[k])p=fail[p];
                    if(s[p+1]==zifu[k])dp[i+1][p+1]+=dp[i][j]*lv[k];
                    else dp[i+1][0]+=dp[i][j]*lv[k];
                }
        double ans=0;
        for(int i=1;i<=m;i++)ans+=dp[i][len];
        printf("%.2lf",ans);cout<<"%"<<endl;
    }
    int main(){
        while(scanf("%d%d",&n,&m)){
            if(!n&&!m)break;
            memset(fail,0,sizeof(fail));
            memset(dp,0,sizeof(dp));
            work();
        }
        return 0;
    }
  • 相关阅读:
    linux嵌入式终端ssh无法输入中文以及删除中文异常
    DNS解析错误导致无法ping通网络
    嵌入式linux 打开ping端口
    嵌入式Linux vim编辑器支持中文
    常见BUG-Web
    考勤项目
    功能测试报告的编写
    04_postman环境变量和身份验证
    03_postman的collection管理
    02_postman断言
  • 原文地址:https://www.cnblogs.com/harden/p/6414266.html
Copyright © 2011-2022 走看看