题目
==
资源限制
时间限制:1.0s 内存限制:256.0MB
问题描述
共有n种图案的印章,每种图案的出现概率相同。小A买了m张印章,求小A集齐n种印章的概率。
输入格式
一行两个正整数n和m
输出格式
一个实数P表示答案,保留4位小数。
样例输入
2 3
样例输出
0.7500
数据规模和约定
1≤n,m≤20
分析
==
这是一道动态规划的问题。根据题意“小A买了m张印章,求小A集齐n种印章的概率。”我们就要想到使用二维数组。
二维数组功能多多,能够记录买了多少张印章,集齐了多少种印章,以及出现这种情况的概率。比如小A买了3张印章,集齐2种印章的概率为0.75,用个二维数组(dp)就可以这么表示:dp[3][2] = 0.75。求买了m张印章,集齐n种印章的概率为dp[m][n],我们只要求出dp[m][n]就能得出正确答案。
dp[m][n] 表示买了m张印章,集齐n种印章的概率。而选取每个印章的概率P就是1/n。
分类讨论
====
很显然,我们不能马上得出结果,必须要先进行分类讨论。
1. 集齐数大于购买数
要集齐的种类还大于购买的数量那样是不可能集齐的。转化成计算机语言就是
if j > i:
dp[i][j] = 0
2.集齐印章种数为1
中华文化博大精深
其实,集齐种数为1是有歧义的。
第一种
我们先来看一下题目,“共有n种图案的印章,每种图案的出现概率相同。小A买了m张印章,求小A集齐n种印章的概率。”第一种集齐印章种数为1的情况是指,输入的n为1,这样的话就是只有1种图案印章,小A无论买多少张印章,只要买了,必定能集齐印章。 转换成计算机语言就是
if n == 1:
dp[X][n] = 1 # X表示任意大于0的整数
我想一开始读者就以为我说的是这种情况,但不是的,这种属于特殊情况,我说的集齐印章种数为1是另外一种。
第二种
因为我们不确定n的值,这里说的集齐印章种数为1指的是,在不确定图案种类数(n)的情况下集齐的印章种数为1。比如说有三种图案云,鸟,花,你买了四张印章,只集齐一种印章的概率就与第一种情况的概率不同,不等于1。你只能四张都是买云或花或鸟。
也许这里就有同学不理解我为什么要引入“集齐印章种数为1”这个概念了。因为我们求dp[m][n]就必须从dp[1][1]…dp[2][1]开始。试想一下,你要求出抛三次硬币都是正面的概率,是不是要通过抛两次硬币都是正面的概率 乘上 第三次抛硬币是正面的概率 得出结果?而两次都是正面又要通过一次是正面的概率乘上第二次是正面的概率…而且“集齐印章种数为1”在整个大类的分类讨论中还是属于特殊情况,我们必须要考虑。
捋清楚什么是特殊情况,什么是特殊情况里面的特殊情况就能接着往下看了。
买的印章数
其实买的印章数也要分情况
-
当买的印章数是1,集齐印章种数也是1。那么买齐的概率一定是1.
-
当买的印章数大于1,集齐的印章种数是1,那样就必须买的印章数都相同,集齐的种数才能是1。
我们以 dp[i][1] (表示买i张印章,集齐一种印章的概率)为例分析第二种情况的概率:每种印章出现的概率是 ),买了 i 张只买一种图案(比如 云)的概率为
),买了i张且买的是任意种图案的概率为
) * n。化简得 **
)。**转换成计算机语言为
if j == 1:
dp[i][j] = (1/n) ** (i-1)
最后
不知道你们用的什么环境,我一般都是用的Python3.6环境和pycharm解释器,没有软件,或者没有资料,没人解答问题,都可以免费领取(包括今天的代码),过几天我还会做个视频教程出来,有需要也可以领取~
给大家准备的学习资料包括但不限于:
Python 环境、pycharm编辑器/永久激活/翻译插件
python 零基础视频教程
Python 界面开发实战教程
Python 爬虫实战教程
Python 数据分析实战教程
python 游戏开发实战教程
Python 电子书100本
Python 学习路线规划
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!