【BZOJ1426】收集郵票 題解 (期望)
阿新 • • 發佈:2020-07-13
題目:有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; }