1. 程式人生 > >[Luogu4550] 收集郵票

[Luogu4550] 收集郵票

copy names 輸出格式 printf gis 每次 Go ret 還需要

題目描述

有n種不同的郵票,皮皮想收集所有種類的郵票。唯一的收集方法是到同學凡凡那裏購買,每次只能買一張,並且買到的郵票究竟是n種郵票中的哪一種是等概率的,概率均為1/n。但是由於凡凡也很喜歡郵票,所以皮皮購買第k張郵票需要支付k元錢。
現在皮皮手中沒有郵票,皮皮想知道自己得到所有種類的郵票需要花費的錢數目的期望。

輸入輸出格式

輸入格式:

一行,一個數字N
N<=10000

輸出格式:

要付出多少錢.
保留二位小數

輸入輸出樣例

輸入樣例#1:
3
輸出樣例#1:
21.25


提交地址 : Luogu4550



題解:

簡單的期望DP;

我們設f[i]表示,已經買了i張郵票,我們要買到n張,還需要買多少次;

f[i] = (i / n) * f[i] + ((n - i) / n) * f[i+1] + 1,什麽意思?

我們有 i/n 的可能買到已經買過的郵票, 有 (n - i) / n 的可能買到沒有買過的郵票乘上相應的數量再加上用的這一次就是結果;

化簡得到 : f[i] = f[i+1] + n / (n - i);

這樣f[n] = 0, 就可以遞推求得f數組;

我們再設g[i], 表示我們已經買了i個郵票,我們要買到n張,還需要多少錢;

g[i] = (i / n) * (g[i] + f[i]) + ((n - i) / n) * (g[i+1] + f[i+1]) + 1,什麽意思?

我們有i張郵票,有 i / n 的可能買到已經買過的郵票, 有 (n - i) / n 的可能買到不一樣的郵票, 乘的後面的g[i] + f[i]是什麽意思?

我們買的是以前買過的,所以乘上g[i] + f[i] * 1,第二個同理;


 
Code:
 1 #include <iostream>
 2 #include <cstdio>
 3 #include <algorithm>
 4 using namespace std;
 5 
 6 double n;
 7 
 8 double f[10010], g[10010];
 9 
10
int main() 11 { 12 cin >> n; 13 14 for (register int i = n - 1 ; i >= 0 ; i --) 15 { 16 f[i] = f[i+1] + n / (n - i); 17 } 18 19 for (register int i = n - 1 ; i >= 0 ; i --) 20 { 21 g[i] = g[i+1] + f[i+1] + (i / (n - i)) * f[i] + n / (n - i); 22 } 23 24 printf("%.2lf", g[0]); 25 return 0; 26 }



[Luogu4550] 收集郵票