ACM里的期望和概率问题 从入门到精通

起因:在2020年一场HDU多校赛上。有这么一题没做出来。

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6829

题目大意:有三个人,他们分别有X,Y,Z块钱(1<=X,Y,Z<=1e6),钱数最多的(如果不止一个那么随机等概率的选一个)随机等可能的选另一个人送他一块钱。直到三个人钱数相同为止。输出送钱轮数的期望,如果根本停不下来(希望のはな繋いだ绊が~),输出-1。

做题过程:很显然我们可以得到一个DP想法dp[i][j]表示钱第二多的和第三多的比第一个人少多少钱。从而dp[i][j]+1=(dp[i-2][j-1]+dp[i-1][j-2])/2,但是很显然,这个状态数是1e12级别的。所以很容易想到结合组合数学,然后我有一个朋友,头脑发热(物理上发烧,心理上膨胀)的乱冲,瞎几把化简。没整出来。我的这位朋友事后登录我的账号写了这个博客。

 

总而言之,我的这位朋友(下称我)去重新整理了一下,期望和概率。

首先,是论文学习:

《信息学竞赛中概率问题求解初探》

《浅析竞赛中一类数学期望问题的解决方法》

《有关概率和期望问题的研究 》

(NOI集训队论文github也可以找到)

看完以后,总结下:第一篇,如果学过概率统计的大学生,可以简单过一下就行了。第二篇和第三篇有些许相似,选一个认真跟着思路读加做题,另外一个就比较容易的过掉了。第二篇比较适合入门,第三个多了一个期望概率系统(一种通常用迭代法情况下的高斯消元方法)

读完以后,对期望概率专题也就有了一个大概的映像了。我简单做了下个人的阅读总结。需要的知识有如下,1,2能让你写出方程,3,4,5能让你得到解法,6,7让你不至于无法实现。

1:组合数学能力(基本的公式运算和变换)

2:概率论知识(全概率,贝叶斯,各种基本概型)

3:DP能力(期望DP,图上树上DP,DP优化。

4:高斯消元解方程

5:迭代法&递推

6:基本数据结构能力(算贡献)

7:基本数论能力(快速幂,卢卡斯等)

题目可以简单分成三类,第一类,DP型和类DP型(迭代法&递推,DP),第二类,数学型(算贡献,解方程,组合数学,直接算公式),第三类,复合型,用数学优化DP的复杂度等。

总的来说,这类题目还是非常DP的,经常是给一个模型,然后你会得到一个变换规则。这个规则有时候会很数学,让你看着就知道这肯定不是DP,比如2017年西安区域赛这题 F God of Gamblers。通过分析规则,我们发现不论如何胜率都是对半,每次的期望得到金币都是0。从而等效于每次只赌1块,得到概率为n/(n+m)。当然这题是签到题,本质上看你敢不敢写(甚至是猜)。大多数情况,你会通过描述状态将变换规则转化成一个方程(不等于DP方程),有时候,这个方程不可避免的有后效性,那么我们可以用迭代法或者当成方程组用高斯消元解(注意精度)。如果可以转化为无后效性的方程,那显然我们已经得到了一个DP的做法,当然,很多时候,你会发现,这个做法铁TLE。这几场HDU多校赛就有几题如此,比如开头那个,也比如这个http://acm.hdu.edu.cn/showproblem.php?pid=6825。开头那个题目,是用先用DP算出一些必要的状态,然后用组合数学描述一部分的状态转移,从而降低时间复杂度。这个题目则是完完全全的组合数学题,和你很容易的就能描述的那个方程没什么太大关系(不过队里有人通过那个得到了一些小数据范围内的数据猜出了公式。。。)

以下是26道题目 后续等待更新。

A:light oj 1010 难度:入门

题目大意:有1—N,N个格子。每个格子有一些金币,路过就能拿到金币。从1开始投骰子前进,如果当前格子前进到的点超过N,就重投。问从1走到N得到的金币总数的期望。

题目分析:经典的丢骰子走格子,用概率DP求期望,倒推求期望。

B:HDU 4870 难度:普通(推荐)

题目大意:

有个人有两个0分账号,他可以打比赛,他每次用分低的那个账号打比赛,有p的概率名列前茅,加50分(上限1000分),否则掉100分(下限0分)。问有一个账号到1000分的概率。

题目分析:

这道题目有很多思路,非常适合给初学者做,这里提供3种。

首先,和之前说的一样,我们可以先描述状态。因为分数是50的倍数,所以把分数都除以50,名列前茅加1分,不然扣两分。用dp[n][m]描述两个账号分数分别为n,m(n>=m)。很容易得到一个状态转移方程dp[n][m]=1+p*dp[n][m+1](当n==m时,应为dp[m+1][n])+(1-p)*dp[n][m-1](若m==0,应为dp[n][0]),我们发现这个方程这个样子非常难看,因为dp[n][m]由dp[n][m+1]和dp[n][m-1]推得。

那么我们要:A 不DP了吧  B   我就是要DP

A:总共只有400个状态,把他们都当成变量高斯消元就行了。高斯消元是O(n^3)时间复杂度,没问题

B:我们把方程修改一下,dp[n][m-1]放到等式的左边。这下就可做了,时间复杂度是O(n^2)。

C:状态真的是400吗?我们可以发现:所有的状态不是都是有用的,为什么呢?升到1000分也就是20的过程一定是(0,0)(1,0)(1,1)(2,1)(2,2)(3,2)(3,3).。。。(19,19)那每一次增加的期望为一个账号0——>1的期望,0——>1的期望,1——>2的期望,1——>2的期望,.。。。18——>19的期望,18——>19的期望,19——>20的期望。则期望总和是一个账号0——>19的期望加上一个账号0——>20的期望。时间复杂度是O(n)。

C:ZOJ 3415 难度:入门

题目大意:每次由1/m的概率回一滴血,否则扣一滴血,共n滴血,问期望上几轮会死。

题目分析:列出状态转移方程,我们发现是等比数列求和问题,不过当m等于2的时候公比是1,要分开来考虑。另外,需要写一个快速幂。

D:Light OJ 1408 难度 偏难(推荐,经典模型)

题目大意:

求投丢的概率为p;那么如果一直投到连续中k1个,或者连续丢k2个,所需要的球的期望;给出p,k1,k2;

题目分析:

千万不要纠结于已经投了多少次之类云云,写了一个到无限的求和,或者什么第几次出局的方程。想想你就知道,这很难做。我们可以用A[i]表示已经投丢了i个,还要丢多少球出局的期望。B[i]表示已经连续投中了i个,还需要投中几个出局的期望。初始状态当然是A[k1]=B[k2]=0。我们写出来以后会发现,这并不好DP。那高斯消元呢?会TLE,不过好在我们发现这个式子可以用数学直接化简。从而解决了这道题目。总结一下,这道题目难点是状态的描述,不能纠结于一些无价值的参量,比如次数,一个好的状态描述等于成功的一半,这非常的DP了。

E Light OJ 1342 难度 偏难

题目大意:

现在有n个物品,他们编号是1-n,每个物品都有一个自己的重量Wi。物品分两类,第一类物品,拿了以后不会放回去。第二类,拿了还会放回去, 每一次随机等概率拿。问使得所有物品都被拿过时拿过的物品的总重量的期望。

题目分析:

老样子,先描述好状态很轻松得到一个方程。这道题目有价值的参量显然是,还剩下的物品总数,第一类物品数量,第二类物品数量,不过它们有一个和的关系,两个就够了。我们这里选择用dp[n][m]表示当前剩下n个一类物品,m个二类物品的期望。那下一次无非是拿一类或二类,问题是重量怎么处理呢?我们很容易发现,对于第二类物品,拿了就会拿出去,又是等概率拿,所以每次拿出的二类物品的期望重量时确定的,即二类物品重量平均值。而一类物品呢?拿了就放不回去,最后每个都拿了且只拿了一次,所以结果加上一类物品的总和就行了。初状态是dp[0][j]和dp[0][i],分别用一个一维的DP预处理一下,再总体DP一下。复杂度是O(n^2)

不过如果你读过我上面提到的三个大佬的论文,并且看过论文题目,你一定知道,一个n面骰子(假设严格随机等概率投),使得所有面都朝上过的次数的期望是1/1+1/2+1/3+1/4...+1/n,也就是调和级数。我们不难发现二类物品就是这个模型,而一类物品对结果的影响就是加上一类物品总重,所以我们可以很轻松的用O(n)的复杂度解决这个问题。

F HDU 6052 难度 难

题目大意:

有一个n*m的矩阵(1<=n,m<=100),问随机选一个子矩阵,内部不同数字个数的期望。 

题目分析:

经典算贡献,官方题解比较反人类(容斥分块单调栈)。不过这道题目只用单调栈就能做。首先转化题目,很容易想到算每种颜色的贡献,随之产生的问题是如何避免重复,很容易想到容斥(不过一看就会tle)。不过,只要每个子矩阵我们一个颜色的不同点只会统计一次就行了,给点规定顺序,是经典的解决方法。我们假设按从上到下,从左到右排序。使得每个矩阵的某种颜色的不同点,只统计按这个顺序最先的那个。遍历每个点,统计多少子矩阵包含它且同一种颜色的点它顺序最先。我们不难发现,子矩阵下界可以无限延申,而左右结都随上界变化而变化,具体来说是随上界向上而变小。我们可以用两个单调栈来维护它(双指针)

G Codeforce 148D 难度 普通

题目大意:

公主和恶龙从一个袋子里轮流抓老鼠,公主先抓,恶龙抓了以后,袋子里的老鼠会被随机吓跑一个。共W个白老鼠,B个黑老鼠,谁先抓到白老鼠的话就赢了。问公主赢的概率。

题目分析:

摆明车马,很容易描述状态dp[n][m]为还剩n个白老鼠,m个黑老鼠时公主的胜率,这里把公主抓 恶龙抓视为一轮操作。概率DP莽过去就完了,老样子需要特殊处理一下边界。

H HDU 4579 难度 偏难

题目大意:

有1-N个格子,你一开始在1号格子,给了你关于在第i个去第j格的概率。问走到n的期望步数。

题目分析:

很容易写出状态转移方程 我们发现这个方程里有11个状态n-5,n-4....n+5,如果我们把n-5放到左边,那方程可以无后效性,也不是不能DP。但是,很明显比较麻烦(我比较懒)。那能不能高斯消元呢?这次有50000个方程,50000个变量。emmm 似乎会tle的样子,不过别急,这道题有个很特殊的地方。就是这是个连续的11个状态,并且每个变量只会出现最多5次,我们可以每次只存5个方程,解出一个变量的值,再加一个方程,再解出下一个变量的值。魔改的高斯消元复杂度只需要16*5*50000。

 I HDU 3366 难度 普通,

题目大意:

有n条路,m块钱。每条路,有pi概率到终点,qi概率交1块钱不然死,1-pi-qi概率不通。问出逃成功概率。(1<=n<=1000,1<=m<=100)

题目分析:

dp[n][m]表示在第1-i条路中选过并且还剩m块钱的出逃成功概率。做起来有点像背包,毕竟概率DP本质上只是DP的内容换成了概率而已。

J UVA 11722 难度 入门

题目大意:

a从[t1,t2]中随机选取,b从[s1,s2]中随机选取,问|a-b|<=w的概率

题目分析:

高中送分概率题(至少我肯定江苏是的),几何概型,画个图就出来了。

K CSU 1912 难度 普通

题目大意:

有n块钱,分给包括你在内的m个人,要求你的钱数是唯一的最多的那个且每个人都有钱,问分法(1<=m<n<=3e5)

题目分析:

枚举你的钱数,以及多少人和你一样多。再结合插板法,由于大数运算,结合卢卡斯。综合一点的组合数学题目。

L UVA 6672 难度 入门

题目大意:

有n个位置,竞选n轮。两种竞选方式,一种是icpc,一种是acm。icpc成功率是acm两倍。竞选n轮,每次决出一个位置,现在你要竞选,分别求出按icpc方式竞选的概率和按acm方式竞选的概率。

题目分析:

用两个数组分别表示有i轮j个人该方式成功。

M HDU 5985 难度 难

题目大意:

有几种硬币,告诉你每种硬币的数量和抛起朝上的概率p(0.4<=p<=0.6)。每次抛起所有硬币,去掉背面朝上的(硬币不会立起来)。如果只剩一种硬币或者没有硬币结束,只剩一种的话叫这种幸运硬币,问每种成为幸运硬币的概率。(n总和小于1e6,种类最多10种)精度1e-6

题目分析:

这道题目很独特,思路比较特殊,一般来说,这种描述状态是和轮数无关的,因为把轮数写进去通常会复杂,惯性思维下我一开始写dp[i][j]为i种当前这种和j个其它,然后我发现,这个转移非常难写,即便优化也没法不tle。然后一个条件吸引了我—— 0.4<=p<=0.6。这个条件很奇怪,不可能只是为了符合现实吧,应该有意义。迷茫了一会儿后发现,进行了很多轮后的胜利对结果的影响应该是忽略不计的。于是把轮数写了进去,描述某一种硬币前j轮死光的概率,从而得到每一种硬币在一定轮数前的胜率。为了达到精度,莽了一个50,后来发现wa了,后来发现要100。

N HDU 5955 难度 难

题目大意:

有n个人投骰子,每个人猜一个长度为l的获胜序列,出现就赢了。问每个人的获胜概率。(1<=n,l<=10)

题目分析:

AC自动机加概率DP,相信是一个不假思索地思路。不过冷静想一想,会tle。听说矩阵优化可卡,不过不想尝试,毕竟我代码不够优美,经常大常数(抱头痛哭)。不过状态数最多只有100,可以高斯消元。

O HDU 5956 难度 偏难

题目大意:

有一棵树,共N个节点,每个节点都有一个信息要送给根节点1。运送中每到一个结点,可以选择换一个信使,需要花P的等待时间 。对于一个信使,跑距离L需要L*L的时间。每个节点都用最优方法送出消息,问用时最多的那个要多少时间。(N ≤ 100000) and P (P ≤ 1000000). 

题目分析:

很显然的树上DP嘛,然后写了方程,发现时间复杂度O(n^2),会tle。我们考虑两个思路。一:方程能后优化。二:方案能否合并,也就是重新定义状态,使得转移子树里的最大值。发现二不好操作,无法避免无后效性。而一可以斜率优化,从而得到正解。

P Gym 100608G 难度 普通

题目大意:

两人轮流摇一个[0,b1]的骰子,各投d次得到一d位b进制数,最后数字大的赢。一:轮流投,二:第一个人投d次之后,第二个人投。两人都采用最佳策略,问两种情况下第一个人的胜率。0<d,b<=10,(b+1)^d<=3000

题目分析:

首先是如何描述状态,很容易想到用dp[i][j][k]表示第一个数是i,第二个数是j的情况下,当前是第k个人填数的情况下。第一个人的胜率,然后模拟填写过程。不过我们知道dp[i][j]的转移方程是求max或者min得到的,不可倒推。因此只能用dfs来写。紧接着的问题是,我们没法用当前值标记某个位填了0。因此我们做一个变换,改填0-b-1为1-b。考虑到比较值的大小是从高位到低位比较大小。这个变换是等价的。从而使得i,j能表示某个位有没有填数,从而使得第三维k可以消掉。(b+1)^d<=3000,时间复杂度也是合法的

Q HDU 5819 难度 普通

题目大意:

数轴上一段0-n+1上有n个棋子分别在1,2,3.。。n上。每个棋子要么往左,要么往右,单位时间走单位距离,到头尽头会回头。两个棋子相遇后会战斗,1/2的概率胜利,胜利的那个接着走,失败的就消失。问第n个棋子活到最后的概率。

题目分析:

一开始看成了每个棋子的胜率,首先发现了同向的棋子之间比较好处理,然后发现了步数有限,而且决斗顺序有一定规律,一个棋子往右,那它左边的情况比较好处理,右边就开始抓瞎了,然后再读了一遍题目,哦。读错题目了,嘿嘿嘿。

只要知道第n个棋子左边多少棋子自左往右就行了。dp[i][j]表示前i个棋子j个往右的概率。如果这个棋子往右,那前i-1个棋子在这个棋子被n干掉前没有机会干掉n。如果这个棋子往左去找n干架了,那它一定干翻了1-i-1。后者是对dp[i-1][j]/(2^j)求和。很容易想到优化。

时间复杂度O(n^2)

R  HDU 4089 难度 偏难

题目大意:

n个人在排队,每次,队首都会有如下4种情况:p1概率无事发生,p2概率跑到队列最后,p3概率离开队列,p4概率停止一切操作。问停止一切操作后,原来的第m号人在队列中顺序小于等于k的概率。

(1 <= M <= N <= 2000) p1+p2+p3+p4=1

题目分析:

很容易描述状态dp[i][j]为共j个人,原来的第m号人在队列第i个(i<=j),通过描述变换规则可以得到一个状态转移方程。问题是如何处理它,篇幅有限,描述下重点,我们让j从1-n循环,j-1的值我们都已经得到,可以视为常数。

剩下的问题大概是这样的X1=Xn*p+C1 X2=X1*p+C2,....Xn=Xn-1*p+Cn。解决方法是迭代,将第n-1个方程代入第n个方程。再把第n-2个方程代入。。。。于是我们消去了X1。。。Xi-1,得到

Xn= ∏((p2/(1-p1))^(j-i))*Ci / (1 - (p2/(1-p1))^j)。得到了一个变量的值,就很容易得到所有的值了。

有一个坑点。很多题解说是p4过小会崩溃,其实这话不完全对,起码没说清楚。本质上的问题是p1+p2接近1以及p1以及p2接近1的话会除0。而判断p4小于eps输出0包括了以上情况,而除了这个本质的问题外,其它p4小于eps的情况,只会导致结果是0,是不会RE的。

S UVA 12230 难度 入门

题目大意:

你在数轴上的0,要到数轴上的D,中间有n条河。每条河宽度为L,左岸坐标为Disti(不一样,河流也不重合),上面有一条船,船头随机等概率向正半轴和负半轴,随即等概率在河中间,船到头就会掉头到另外一边,速度为V(带不带人都一样),你只能坐船过河。你走路速度为1,问你到达目的地的期望时间。

题目分析:

船头向正半轴,那要过河需要行驶距离在[2L,3L]里均匀分布,向负半轴,在[L,2L]里均匀分布,所以平均为2L。一个循环搞定。

T UVA 1639

题目大意:

鲁迅(鲁迅确实喜欢吃糖)有两个糖罐子A,B,都有n个糖果(1<=n<=2e5)。每天有p的概率从A拿一个糖吃,1-p概率从B拿一个糖吃。有一天,他打开一个罐子发现它空了,问另一个罐子里糖果数量的期望。

题目分析:

枚举一下另一个罐子的糖果数量,经典二项分布。遗憾的是这个题目的精度已经杀疯了,需要用long double加log。。。精度杀我!

U UVA 10900 难度 入门

题目大意:你答题,依次面对第1,2.。。n个问题。初始奖金1元。第i个题目你可以选择

1:不回答,拿着已经拿到的奖金走

2:回答,若正确奖金变成2^i元,错误则失去所有奖金离开。

问你最优策略下,期望奖金。

题目分析:

道理很明白,设答对第i题概率为p,dp[i]=max(2^(i-1),p*dp[i+1],dp[n+1]=2^n;倒推。下面就是数学问题了。

V Lightoj 1151 难度 普通

题目大意:给你100个方格,编号为1到100,每次你丢一次骰子,决定你下次往前走多少步,有些方格会有一些梯子或者蛇,使得你到该格子时直接转向另一个格子,若你当前的位置+骰子的点数>100,则在原地重新丢一次,问你到编号为100的格子所投骰子次数的期望是多少?

题目分析:有一道类似的题目忘了那里的了,梯子有序,所以可以dp做,和A差不多,只要特殊处理一下梯子就行了。这里不行,梯子无序,那就高斯消元。老策略了。

W Lightoj 1274 难度 普通 

题目大意:

你是OI骗分小能手,现在测试数据n组,其中有m组YES(m是算出来的),n-m组NO。你打算这样骗分,先输出YES,然后下面每次都输出上一组的正确答案(骗分导论下一版稿费一定有你的份)。现在问你你不能通过的数据组数的期望。(1<=n<=5000)

题目分析:

很容易想到描述状态为dp[i][j][k]为从前往后填,填了i个yes,j个no,k描述前一个是yes还是no,然后用滚动数组优化。AC以后看了看题解,有直接公式算的。就思考了一下,贡献包含yes在1到n-1的位置并且后面是no,以及在2-n的位置前面是no。还有一个额外的no在开头的贡献。设有a组yes,b组no。所以是(a+b-1)/(a+b)*b/(a+b-1)*2*a+1/(a+b)*b。从而可以公式求解、

X light oj 1265 难度 普通

题目大意:

现在有t只老虎,d只鹿还有你,每天会随机选两个动物相遇。两个老虎相遇,两只老虎都会死,老虎遇到鹿或者你,你或鹿被吃,两只鹿相遇无事发生,你碰到鹿,可以选择杀或者不杀鹿。老虎死光了你就安全了,问你安全的最大概率。

题目分析:

很容易想到用dp[i][j]表示还剩t个老虎和d个鹿。你的生存概率。网上有题解说鹿没有影响,这个确实没有想到,主要是看到数据范围习惯性n^2dp不假思索草过去了。

Y light oj 1284 难度 普通

题目大意:

有一个x*y*z的立方体,内有若干整点,每次随机选一个子立方体。问被选到奇数次的点的个数的期望。

题目分析:每个点每次都是单独的,能算出每个点被选中的概率,也就是x,y,z都被选中在区间里。

Z light oj 1287 难度 普通

题目大意:

有n个城市(n<=15),一个人一开始在一个城市,他等可能的选择去往一个其它与之有路径直接相连的城市或者停留5分钟,问遍历完的期望。

题目分析:

经典的随机游走问题,这里由于城市数量,很容易想到状态压缩DP,用已经遍历过的城市和当前所在点记录状态。随机游走问题也有一篇集训队论文,可以学习。

最后总结一下一些稍显特殊的处理方法

1:算贡献(其实已经是基本操作了,但是描述状态的时候有时候会忽略这个思路,描述的状态不一定是结果,也可以是贡献)

2:魔改高斯消元,方程组形式特殊的情况下,可以魔改高斯消元

3:对于如R hdu4089的情况,迭代求公式先求出一个值。

4:大多数情况下,我们不会考虑次数描述状态,但是当精度和概率范围比较确定的时候,一定次数后的结果将可以忽略不计

5:精度!精度!精度!long double+log可以更加精确。对于除0的判断结合精度(其实可以基本操作)

posted @ 2020-08-08 20:48  idyllic  阅读(1850)  评论(1编辑  收藏  举报