zoukankan      html  css  js  c++  java
  • HDU 3689 Infinite monkey theorem (KMP+DP)

    题目大意:一群猴子打字,给定猴子输入每种字符的概率以及输入次数,求输出的文本中出现指定字符串的概率

    强烈建议看这篇文章:http://www.matrix67.com/blog/archives/366 里面对这道题的分析很详细

    思路比较清奇,我们先用KMP求出指定串的next,接下来是DP的过程

    f[i][j]表示输入了i个字符,匹配到了第j个的概率

    这道题是一个贪心的思路,我们在第j位可以填上任意字符,而如果第j位填上的字符不符合原串,即在当前第j位匹配失败,我们要从j-1的位置不断向前跳next(保证前缀都相同),直到匹配成功或者整个串的无法匹配,然后我们乘上该字符出现的概率即可。

     1 #include <cstdio>
     2 #include <algorithm>
     3 #include <cstring>
     4 #include <vector>
     5 #define N 1010
     6 #define M 30
     7 #define L 12
     8 #define mod 1000000007
     9 #define ui unsigned int
    10 #define ll long long
    11 #define dd double
    12 #define idx(x) x-'a'+1
    13 using namespace std;
    14 
    15 int T,n,m,len;
    16 int nxt[L];
    17 dd f[N][L],c[M];
    18 char t[L];
    19 void get_kmp()
    20 {
    21     int i=0,j=-1;
    22     nxt[0]=-1;
    23     while(i<len)
    24     {
    25         if(j==-1||t[i]==t[j])
    26         {
    27             i++;
    28             j++;
    29             nxt[i]=j;
    30         }else{
    31             j=nxt[j];
    32         }
    33     }
    34 }
    35 
    36 dd solve()
    37 {
    38     f[0][0]=1;
    39     for(int i=1;i<=m;i++)
    40     {
    41         for(int j=1;j<=len;j++)
    42         {
    43             for(int k=1;k<=26;k++)
    44             {
    45                 int p=j-1;
    46                 while(p!=-1&&idx(t[p])!=k) p=nxt[p];
    47                 f[i][p+1] += f[i-1][j-1]*c[k];
    48             }
    49         }
    50     }
    51     dd ans=0;
    52     for(int i=1;i<=m;i++) ans+=f[i][len];
    53     return ans*(dd)100;
    54 }
    55 
    56 int main()
    57 {
    58     //freopen("aa.in","r",stdin);
    59     while(1)
    60     {
    61         memset(f,0,sizeof(f));
    62         memset(c,0,sizeof(c));
    63         memset(nxt,0,sizeof(nxt));
    64         scanf("%d%d",&n,&m);
    65         if(n==0&&m==0) break;
    66         for(int i=1;i<=n;i++)
    67         {
    68             scanf("%s",t);
    69             scanf("%lf",&c[idx(t[0])]);
    70         }
    71         memset(t,0,sizeof(t));
    72         scanf("%s",t);
    73         len=strlen(t);
    74         get_kmp();
    75         printf("%.2lf",solve());
    76         putchar('%');
    77         puts("");
    78     }
    79     return 0;
    80 }
    81 
    82     
    83     
  • 相关阅读:
    第一阶段冲刺4
    用户场景分析
    最小不重复数
    BOM
    虚拟机下ubuntu系统设置分辨率
    富文本编辑器KindEditor使用
    页面路径设置
    VMware虚拟机不能上网的问题
    Apache Tomcat/7.0.42配置用户
    JFreeChart 横轴文字竖着显示
  • 原文地址:https://www.cnblogs.com/guapisolo/p/9696937.html
Copyright © 2011-2022 走看看