• hdu3689(kmp+dp)


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

    解法:dp+kmp优化。ans[i][j]表示i长度,走到了s的j位置的概率,当然这是在i之前没有出现s的前提下(在状态转移时候已经保证了这一点);然后最后的概率就是1-m长度的串分别最后出现s的概率之和。


    代码:

    /******************************************************
    * @author:xiefubao
    *******************************************************/
    #pragma comment(linker, "/STACK:102400000,102400000")
    #include <iostream>
    #include <cstring>
    #include <cstdlib>
    #include <cstdio>
    #include <queue>
    #include <vector>
    #include <algorithm>
    #include <cmath>
    #include <map>
    #include <set>
    #include <stack>
    #include <string.h>
    //freopen ("in.txt" , "r" , stdin);
    using namespace std;
    
    #define eps 1e-8
    #define zero(_) (_<=eps)
    const double pi=acos(-1.0);
    typedef long long LL;
    const int Max=100010;
    const LL INF=0x3FFFFFFF;
    int n,m;
    struct point
    {
        char c;
        double p;
    } points[30];
    map<char,double> maps;
    string s;
    double ans[1010][12];
    int Next[30];
    void get_next()
    {
        int i=0;
        int j=Next[0]=-1;
        int len=s.size();
        while(i<len)
        {
            while(j!=-1&&s[i]!=s[j]) j=Next[j];
            Next[++i]=++j;
        }
    }
    int OK(string t)
    {
        for(int i=0;i<t.size();i++)
        {
            if(t.substr(i,t.size()-i)==s.substr(0,t.size()-i))
            return t.size()-i;
        }
        return 0;
    }
    int get(int j,int k)
    {
        while(j!=-1&&s[j]!=points[k].c)
        {
            j=Next[j];
        }
        return j+1;
    }
    int main()
    {
        while(scanf("%d%d",&n,&m)==2)
        {
            if(n==0&&m==0)
            break;
            memset(ans,0,sizeof ans);
            for(int i=0; i<n; i++)
            {
                cin>>points[i].c>>points[i].p;
            }
            cin>>s;
            get_next();
            ans[0][0]=1.0;
            for(int i=1; i<=m; i++)
            {
                for(int j=1; j<=s.size(); j++)
                    for(int k=0; k<n; k++)
                    {
                      ans[i][get(j-1,k)]+=ans[i-1][j-1]*points[k].p;
                    }
            }
            double out=0;
            for(int i=1;i<=m;i++)
            out+=ans[i][s.size()];
            printf("%.2lf%%
    ",out*100);
        }
        return 0;
    }
    

  • 相关阅读:
    学习制作操作系统 0
    阅读《C陷阱与缺陷》的知识增量
    CSS 优先级和特指度
    openCV2马拉松第19圈——Harris角点检測(自己实现)
    Cacti监控mysql数据库server实现过程
    ledisdb:支持类redis接口的嵌入式nosql
    03005_SQL查询语句
    通过smtp直接发送邮件
    XML 解析默认去掉命名空间和注释
    C# /VB.NET 创建PDF项目符号列表和多级编号列表
  • 原文地址:https://www.cnblogs.com/mfrbuaa/p/4253028.html
Copyright © 2020-2023  润新知