【蓝桥杯试题】试题 算法训练 印章

试题 算法训练 印章

资源限制

时间限制:1.0s 内存限制:256.0MB

问题描述

  共有n种图案的印章,每种图案的出现概率相同。小A买了m张印章,求小A集齐n种印章的概率。

输入格式

  一行两个正整数n和m

输出格式

  一个实数P表示答案,保留4位小数。

样例输入

2 3

样例输出

0.7500

数据规模和约定

  1≤n,m≤20

本题思路如下:

将求解概率问题分解为求解每取一个印章时的概率问题。

如:印章种类为2,购买数量为3,在仅摸了一次时,总计有印章种类数为1的概率为100%;

在摸了两次时,种类为1的概率为50%,种类为2的概率也为50%。

此时可列下表:

个数/种类数12
1100%0
250%50%
325%75%

注意观察规律,每一行的概率和固定为100%不会变,且重点是:每一行的概率都由前一行的概率和这一次印章出现的概率所决定,记个数为i,种类数为j,概率为p,有以下推导公式:

p[i][j]=p[i-1][j-1]*(n-j)/n+p[i-1][j]*(j+1)/n

公式描述不够清晰,可以简单理解为,前一行的同列和前一行的前一列两个概率分别乘以得到另一种未拥有印章的概率。

需要提醒的是,当种类数为1时,只要个数大于0,那么概率始终为100%;当购买个数小于种类数时,概率始终为0。

那么解决完特殊情况,获得了推导公式,那么我们可以使用记忆搜索法来求解该问题:

n,m=list(map(int,input().split()))
x=[[0 for i in range(min(i+1,n))] for i in range(m)]
x[0][0]=1
i=0
j=0
for i in range(1,m):
    for j in range(len(x[i])):
        if(i-1>-1 and j-1>-1):
            try:x[i][j]=x[i-1][j-1]*(n-j)/n+x[i-1][j]*(j+1)/n
            except:x[i][j]=x[i-1][j-1]*(n-j)/n
        else:
            if(j+1==n):x[i][j]=x[i-1][j-1]*(n-j)/n
            else:x[i][j]=x[i-1][j]*(j+1)/n
if(m<n):
    print('0.0000')
else:
    print('%.4f'%x[i][j])

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值