收集郵票(概率dp)
阿新 • • 發佈:2020-08-17
題目大意
有n種不同的郵票,皮皮想收集所有種類的郵票。唯一的收集方法是到同學凡凡那裡購買,每次只能買一張,並且買到的郵票究竟是n種郵票中的哪一種是等概率的,概率均為1/n。但是由於凡凡也很喜歡郵票,所以皮皮購買第k張郵票需要支付k元錢。 現在皮皮手中沒有郵票,皮皮想知道自己得到所有種類的郵票需要花費的錢數目的期望。
輸入格式
- 一行,一個數字N N<=10000
輸出格式
- 要付出多少錢. 保留二位小數
演算法分析
- 顯然是個期望dp
- 首先定義dp方程
設f[i] 表示取到 i 種郵票之後,把其它所有郵票取完的期望次數
g[i] 表示取到i 種郵票之後,把其它所有郵票取完的期望價格 - 那麼f[i]的轉移就是 \(f[i] = \frac{i}{n}*f[i]\)
- g[i] 的轉移就是 $g[i] = \(\frac{i}{n} * (g[i] + f[i] + 1)\) + \(\frac{n-i}{n}\) * (g[i+1] + f[i+1] + 1) 然後移項可得 g[i] = \(\frac{i}{n-i}\)
- 這樣我們就可以遞推求解了
Code
#include <bits/stdc++.h> using namespace std; const int maxn = 1e5 + 10; int n; double f[maxn],g[maxn]; int main(){ scanf("%d",&n); for(int i=n-1;i >= 0;--i) { f[i]=f[i+1]+(1.0*n)/(1.0*(n-i)); g[i]=(1.0*i)/(1.0*(n-i))*(f[i]+1)+g[i+1]+f[i+1]+1; } printf("%.2lf\n",g[0]); return 0; }