BZOJ 1426 收集郵票 概率DP
阿新 • • 發佈:2019-02-13
題目描述 Description
有n種不同的郵票,皮皮想收集所有種類的郵票。唯一的收集方法是到同學凡凡那裡購買,每次只能買一張,並且買到的郵票究竟是n種郵票中的哪一種是等概率的,概率均為1/n。但是由於凡凡也很喜歡郵票,所以皮皮購買第k張郵票需要支付k元錢。現在皮皮手中沒有郵票,皮皮想知道自己得到所有種類的郵票需要花費的錢數目的期望。
輸入描述 Input Description
一行,一個數字N
輸出描述 Output Description
要付出多少錢. 保留二位小數
樣例輸入 Sample Input
3
樣例輸出 Sample Output
21.25
資料範圍及提示 Data Size & Hint
Solution
用表示現在取到張郵票,要取完剩下郵票的期望次數
顯然
現在已經取得張郵票,所以下一次取郵票有的概率取到已經有的,期望為
有的概率取到沒有的,期望為,這次取郵票的期望為1,所以總期望為:
化簡可得:
用 表示現在取到張郵票,要取完剩下郵票的期望價格
顯然
現在已經取得張郵票,所以下一次取郵票有的概率取到已經有的,期望為,有的概率取到沒有的,期望為所以總期望為:
化簡可得:
前面的推導貌似很自然的樣子,但是為啥的推導式看著就那麼奇怪呢?
那是因為式子的結構表示的是每次都將後面取到的郵票費用+1(總費用+f[i]),再加上自己的費用(+1)
這樣就很好理解了
為啥不是我也想了很久
因為推導過來每次的貢獻是不相同的
比如說所有情況中有1次需要取2張,1次需要取3張,那麼總貢獻為,而期望次數為2.5,顯然是不對的…
程式碼比思考簡單多了
#include <bits/stdc++.h>
using namespace std;
int n;
double f[10005],g[10005];
int main() {
scanf("%d",&n);
for(int i=n-1;~i;--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;
}