King Arthur is an narcissist who intends to spare no coins to celebrate his coming K-th birthday. The luxurious celebration will start on his birthday and King Arthur decides to let fate tell when to stop it. Every day he will toss a coin which has probability p that it comes up heads and 1-p up tails. The celebration will be on going until the coin has come up heads for K times. Moreover, the king also decides to spend 1 thousand coins on the first day's celebration, 3 thousand coins on the second day's, 5 thousand coins on the third day's ... The cost of next day will always be 2 thousand coins more than the previous one's. Can you tell the minister how many days the celebration is expected to last and how many coins the celebration is expected to cost?
1 1 1 0.5 0
1.000 1.000 2.000 6.000
对于期望问题,我是第一次接触,花了大量的时间入门,直到现在做期望题还是基本得先看别人的题解才有思路,因为期望问题涉及到很多数学运算,大量的数学规律推导公式,高斯消元法的使用也很广泛,对线性代数的使用要求也比较高,所以刚刚开始肯定会很有种自己蠢哭了就是理解不了的感觉,这是很正常的。学期望得静下心来,一步一步的解决问题,才会有收获。
言归正传,先来看下这道题。
题意:每天抛一个硬币,硬币正面朝上的几率是p,直到抛出k次正面为止结束,第一天抛硬币需花费1,第二天花费3,然后是5,7,9……以此类推,让我们求出抛硬币的天数的期望和花费的期望。
此题应该有两种解决思路,第一种是对概率进行DP求解,第二种是直接推导出期望的数学公式。在这里小编给出两种思路的详解和代码。
(1) DP求解:
首先可以尝试直接去理解天数n就等于k/p,因为投硬币属于独立重复实验,所谓独立重复实验,是在同样的条件下重复地、各次之间相互独立地进行的一种实验,这个通俗来理解就是……比如你的投篮命中率为25%,那平均进一球要投4个,那要进k个就要平均投4k次。同理,天数就等于k/p。
可能这样理解有点牵强,那接下来我们看看DP思想下的理解,假设天数的期望为E(x),达到E(x)可以有两种途径,可以这样去理解:1.在已经投出k-1个硬币的情况下,再投出1个正面的硬币达到k个,其期望为p*(E(x-1)+1);2.在已经投出k个硬币的情况下,再投出一个反面的硬币使得投出正面的硬币数仍然定格在k个,其期望为(1-p)*(E(x)+1)。这样我们就得到了E(x)的递推公式,E(x) = p*(E(x-1)+1)+(1-p)*(E(x)+1),用过化简我们可以得到E(x) = E(x-1)+1/p,此时我们要是对E(x)进行迭代就可以同样得到E(x) = x/p。
接下来是花费的期望,我们设F(x)为花费的期望,同理可以得到F(x)的递推公式F(x) = p*(F(x-1)+E(x-1)*2+1)+(1-p)*(F(x)+E(x)*2+1)。既然得到了递推公式,我们就可以通过递推求解了。
#include <cstdio> double E[1002],F[1002]; int main() { int n; double p; while(scanf("%d",&n)&&n!=0) { scanf("%lf",&p); E[0] = 0; F[0] = 0; for(int i=1; i<=n; i++)//F(x)=p(F(x-1)+E(x-1)*2+1)+(1-p)(F(x)+E(x)*2+1) { E[i] = i/p; F[i] = F[i-1]+2*E[i-1]-2.0*E[i]+(1+2.0*E[i])/p; } printf("%.3lf %.3lf\n",E[n],F[n]); } return 0; }
接下来我们进行数学公式的推导,这里给出详细的推导公式,集中注意力,你会发现推导过程相当神奇!
f[i]为第i天结束的概率,则f[i]=c(i-1,k-1)*p^k*(1-p)^(i-k),然而总概率为 ∑f[i]=1,其中i∈[k,+∞),以下均为此范围,则有,p^k*∑(c(i-1,k-1)*(1-p)^(i-k))=1,即:∑(c(i-1,k-1)*(1-p)^(i-k))=1/(p^k),该等式下面有用:
则天数的期望为:
ans1=∑(i*f[i])
=p^k*∑(i*c(i-1,k-1)*(1-p)^(i-k))
=k*p^k*∑(c(i,k)*(1-p)^(i-k))
=k*p^k/p^(k+1)
=k/p
花费的期望为:
ans2=∑(i*i*f[i])
=p^k*∑(i*i*c(i-1,k-1)*(1-p)^(i-k))
=k*p^k*∑(i*c(i,k)*(1-p)^(i-k))
=k*p^k*∑((i+1)*c(i,k)*(1-p)^(i-k))-k*p^k*∑(c(i,k)*(1-p)^(1-k))
=k*(k+1)*p^k*∑(c(i+1,k+1)*(1-p)^(i-k))-ans1 //将i+1放进去
=k*(k+1)*p^k/(p^(k+2))-ans1
=k*(k+1)/p^2-ans1
有了这两个通项公式,我们便可以直接求出答案。
#include<stdio.h>//数学推导 int main() { int k; double p,res1,res2; while(scanf("%d",&k)&&k) { scanf("%lf",&p); res1 = k/p; res2 = k*(k+1)/(p*p)-res1; printf("%.3f %.3f\n",res1,res2); } }