【BZOJ1426】收集邮票 题解 (期望)

题目:有n种不同的邮票,皮皮想收集所有种类的邮票。唯一的收集方法是到同学凡凡那里购买,每次只能买一张,并且买到的邮票究竟是n种邮票中的哪一种是等概率的,概率均为1/n。但是由于凡凡也很喜欢邮票,所以皮皮购买第k张邮票需要支付k元钱。
现在皮皮手中没有邮票,皮皮想知道自己得到所有种类的邮票需要花费的钱数目的期望。

----------------------------------

考虑递推。

设$f[i]$表示取了$i$种邮票,要取完剩下邮票的期望次数。显然$f[n]=0$。有$\frac{i}{n}$的概率是取到已经取过的,期望是$\frac{i}{n}*f[i]$,有$\frac{n-i}{n}$的概率取到没取过的,期望是$\frac{n-i}{n}*f[i+1]$。这一次取过后次数+1。所以$f[i]=\frac{i}{n}*f[i]+\frac{n-i}{n}*f[i+1]+1$。化简一下:$f[i]=f[i+1]+\frac{n}{n-i}$。

设$g[i]$表示已经取了$i$种邮票,要取完剩下的邮票的期望金钱。显然$g[n]=0$。有$\frac{i}{n}$的概率是取到已经取过的,期望是$\frac{i}{n}*(g[i]+f[i]+1)$。有$\frac{n-i}{n}$的概率取到没取过的,期望是$\frac{n-i}{n}*(g[i+1]+f[i+1]+1)$。化简后就是$g[i]=\frac{i}{n-i}*f[i]+g[i+1]+f[i+1]+\frac{n}{n-i}$。

顺便一提:期望DP的定义一般是“已经……还需要……的期望”。

代码:

#include<bits/stdc++.h>
using namespace std;
int n;
double f[100005],g[100005];
int main()
{
    cin>>n;
    for (int i=n-1;i>=0;i--) f[i]=f[i+1]+(double)n/(double)(n-i);
    for (int i=n-1;i>=0;i--) g[i]=(double)i/(double)(n-i)*f[i]+g[i+1]+f[i+1]+(double)n/(double)(n-i);
    printf("%.2lf",g[0]);
    return 0;
}

 

posted @ 2020-07-13 16:15  我亦如此向往  阅读(188)  评论(0编辑  收藏  举报