zoukankan      html  css  js  c++  java
  • tyvj P1519 博彩游戏(AC自动机+DP滚动数组)

    P1519 博彩游戏

    背景

    Bob最近迷上了一个博彩游戏……

    描述

    这个游戏的规则是这样的:
    每花一块钱可以得到一个随机数R,花上N块钱就可以得到一个随机序列;
    有M个序列,如果某个序列是产生的随机序列的子串,那么就中奖了,否则不中。
    Bob会告诉你这M个序列,和身上有的钱的总数N,当然还有R的范围。
    请你告诉Bob中奖的概率有多少?

    输入格式

    第一行三个用空格隔开的数N、M和R的范围R。
    其中1<=R<=9,0<N<=60,0<M<=20000。
    下面M行每行一个字符串(长度小于等于20),字符串的每一位范围在1-r之间
    保证必要运算都在64位整型范围内。

    输出格式

    一行一个实数,表示中奖的概率(保留小数点后5位小数)。

    测试样例1

    输入

    5 1 3 
    1

    输出

    0.86831

    备注

    数据分布:
    第1个点~第10个点,每个点5分;
    第11个点~第15个点,每个点10分。

    对于样例的解释:
    随机序列一共有3^5=243个,其中包含"1"的个数为211个,则概率为211/243=0.86831Bob HAN

    【思路】

          

       AC自动机+DP。

           与bzoj1030一样思路都是要转化为求AC自动机上不经过单词节点的方案。不同的是这个题需要用滚动数组不然MLE <_<

           尼玛tyvj上double要用%f,让我WA了千万发,我说以前怎么提交不过WTF

    【代码】

     1 #include<set>
     2 #include<cstdio>
     3 #include<queue>
     4 #include<cstring>
     5 #include<iostream>
     6 using namespace std;
     7 typedef long long LL;
     8 const int N=20000+5,L=20+5;
     9 const int node = N*L;
    10 const int sigma = 10;
    11 
    12 char s[L]; int n,m,r; LL d[2][node];
    13 
    14 struct ACauto{
    15     int ch[node][sigma],f[node],val[node],sz;
    16     void clear() {
    17         sz=1; memset(ch[0],0,sizeof(ch[0]));
    18     }
    19     void insert(char *s) {
    20         int n=strlen(s),u=0;
    21         for(int i=0;i<n;i++) {
    22             int c=s[i]-'1';
    23             if(!ch[u][c]) {
    24                 memset(ch[sz],0,sizeof(ch[sz]));
    25                 val[sz]=0; ch[u][c]=sz++;
    26             }
    27             u=ch[u][c];
    28         }
    29         val[u]=1;
    30     }
    31     void get_Fail() {
    32         queue<int> q;
    33         f[0]=0;
    34         for(int c=0;c<r;c++) 
    35             if(ch[0][c]) f[ch[0][c]]=0,q.push(ch[0][c]);
    36         while(!q.empty()) {
    37             int qr=q.front(); q.pop();
    38             for(int c=0;c<r;c++) {
    39                 int u=ch[qr][c]; if(!u) continue;
    40                 q.push(u);  int v=f[qr];
    41                 while(v&&!ch[v][c]) v=f[v];
    42                 if(val[ch[v][c]]) val[u]=1;
    43                 f[u]=ch[v][c];
    44             }
    45         }
    46      }
    47 }ac;
    48 int que[2][N],cnt[2];
    49 int main() {
    50     //freopen("in.in","r",stdin);
    51     //freopen("out.out","w",stdout);
    52     scanf("%d%d%d",&m,&n,&r);
    53     ac.clear();
    54     for(int i=0;i<n;i++) {
    55         scanf("%s",s); ac.insert(s);
    56     }
    57     ac.get_Fail();
    58     d[0][0]=1;
    59     int x=0;
    60     for(int i=1;i<=m;i++) {
    61         x^=1;
    62         memset(d[x],0,sizeof(d[x]));
    63         for(int j=0;j<ac.sz;j++) if(!ac.val[j]&&d[x^1][j]) {
    64             for(int c=0;c<r;c++) {
    65                 int k=j; while(!ac.ch[k][c]&&k) k=ac.f[k];
    66                 d[x][ac.ch[k][c]]=d[x^1][j]+d[x][ac.ch[k][c]];
    67             }
    68         }
    69     }
    70     LL ans1=0,ans2=1;
    71     for(int i=1;i<=m;i++) ans2*=(LL)r;
    72     for(int i=0;i<ac.sz;i++)
    73         if(!ac.val[i]) ans1+=d[x][i];
    74     double f=((double)ans2-(double)ans1)/(double)ans2;
    75     printf("%.5f
    ",f);
    76     return 0;
    77 }
  • 相关阅读:
    安全传输平台项目扩展——keymngserver重构-硬件扩展
    安全传输平台项目扩展——C复习-C++复习-keymngclient重构
    安全传输平台项目——客户端代码移植-项目模块总结
    安全传输平台项目——配置管理终端-读写数据库
    根号分治刷题记录
    使用netsh命令来管理IP安全策略
    关于make_shared无法访问非公有构造函数的解决方法
    两两交换链表中的节点-递归解法
    Spring 的 AOP 简介
    Spring IOC和DI 注解开发
  • 原文地址:https://www.cnblogs.com/lidaxin/p/5196335.html
Copyright © 2011-2022 走看看