1. 程式人生 > 實用技巧 >【BZOJ1426】收集郵票 題解 (期望)

【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; }