您的位置:首页 > 其它

tyvj P1519 博彩游戏

2017-05-24 16:15 288 查看
P1519 博彩游戏

时间: 1000ms / 空间: 131072KiB / Java类名: Main


背景

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

【分析】

tyvj评测姬已死233

同bzoj 1030 文本生成器

唉曾经还在tyvj上天天刷金币来着...

【代码】

#include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>
#define ll long long
#define M(a) memset(a,0,sizeof a)
#define fo(i,j,k) for(i=j;i<=k;i++)
using namespace std;
const int mxn=400005;
char s[mxn];
queue <int> q;
ll ans,sum=1;
ll dp[101][mxn];
int n,m,r,T,num;
struct node {int fail,cnt,son[10];} a[mxn];
inline void trie()
{
scanf("%s",s+1);
int i,j,x=0,len=strlen(s+1);
fo(i,1,len)
{
int c=s[i]-'0';
if(!a[x].son[c])
a[x].son[c]=(++num);
x=a[x].son[c];
}
a[x].cnt=1;
}
inline void build()
{
int i,j,x=0;
fo(i,1,r) if(a[0].son[i]) q.push(a[0].son[i]);
while(!q.empty())
{
x=q.front(),q.pop();
int fail=a[x].fail;
fo(i,1,r)
{
int y=a[x].son[i];
if(y) q.push(y),a[y].fail=a[fail].son[i];
else a[x].son[i]=a[fail].son[i];
}
a[x].cnt|=a[fail].cnt;
}
}
int main()
{
int i,j,k;
scanf("%d%d%d",&n,&m,&r);
fo(i,1,m)
trie();
build();
dp[0][0]=1;
fo(i,1,n)
fo(j,0,num) if(!a[j].cnt)
fo(k,1,r)
dp[i][a[j].son[k]]+=dp[i-1][j];
fo(j,0,num) if(!a[j].cnt) ans+=dp
[j];
fo(i,1,n) sum=sum*r;
printf("%.5lf\n",(double)(sum-ans)/(double)sum);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: