题意
Description
有 n n n 种不同的邮票,皮皮想收集所有种类的邮票。唯一的收集方法是到同学凡凡那里购买,每次只能买一张,并且 买到的邮票究竟是 n n n 种邮票中的哪一种是等概率的,概率均为 1 n \frac{1}{n} n1。但是由于凡凡也很喜欢邮票,所以皮皮购买第k 张邮票需要支付 k k k 元钱。现在皮皮手中没有邮票,皮皮想知道自己得到所有种类的邮票需要花费的钱数目的期望。
Format
Input
一行,一个数字 n n n
Output
要付出多少钱. 保留二位小数
Samples
输入数据 1
3
输出数据 1
21.25
1 ≤ n ≤ 1 0 4 1\leq n\leq 10^4 1≤n≤104
思路
这一道题目堪称牛逼,需要数学功底。
设 P ( x , i ) P(x,i) P(x,i) 表示买 x x x 次能从 i i i 种买到 n n n 种的概率
设 f i f_i fi 表示现在有 i i i 张,买到 n n n 张的期望。
那么有:
f i = ∑ x = 0 ∞ x × P ( x , i ) ⇔ f i = n − i n × f i + 1 + i n × f i + 1 ⇔ n × f i = ( n − i ) × f i + 1 + i × f i + n ⇔ ( n − i ) × f i = ( n − i ) × f i + 1 + n ⇔ f i = f i + 1 + n n − i . f_i=\sum_{x=0}^\infty x\times P(x,i)\\ \begin{align} &\Leftrightarrow f_i=\frac{n-i}{n}\times f_{i +1} + \frac{i}{n}\times f_i+1\\ &\Leftrightarrow n\times f_i=(n-i)\times f_{i+1}+i\times f_i+n\\ &\Leftrightarrow (n-i)\times f_i=(n-i)\times f_{i+1}+n\\ &\Leftrightarrow f_i=f_{i+1}+\frac{n}{n-i}. \end{align} fi=x=0∑∞x×P(x,i)⇔fi=nn−i×fi+1+ni×fi+1⇔n×fi=(n−i)×fi+1+i×fi+n⇔(n−i)×fi=(n−i)×fi+1+n⇔fi=fi+1+n−in.
显然 f n = 0. f_n=0. fn=0.
考虑设 g i , j g_{i,j} gi,j 表示有 i i i 张,下一张是 j j j 的期望。
显然: g i , j → g i , j + 1 g_{i,j}\rightarrow g_{i,j+1} gi,j→gi,j+1 的概率为 i n \frac{i}{n} ni, g i , j → g i + 1 , j + 1 g_{i,j}\rightarrow g_{i+1,j+1} gi,j→gi+1,j+1 的概率为 n − i n \frac{n-i}{n} nn−i,并且付出代价为 j . j. j.
显然有:
g i , j = i n × g i , j + 1 + n − i n × g i + 1 , j + 1 + j g_{i,j}=\frac{i}{n}\times g_{i,j+1}+\frac{n-i}{n}\times g_{i+1,j+1}+j gi,j=ni×gi,j+1+nn−i×gi+1,j+1+j
因为这是一个递推式,不妨考虑它的性质:
g i , j = ∑ x = 0 ∞ [ j + ( j + 1 ) + ⋯ + ( x + j − 1 ) ] × P ( x , i ) = ∑ x = 0 ∞ x × ( x + 2 × j − 1 ) 2 × P ( x , i ) \begin{align} g_{i,j}&=&&\sum_{x=0}^\infty\left[j+(j+1)+\dots+(x+j-1) \right]\times P(x,i)\\ &=&&\sum_{x=0}^\infty\frac{x\times(x+2\times j-1)}{2}\times P(x,i)\end{align} gi,j==x=0∑∞[j+(j+1)+⋯+(x+j−1)]×P(x,i)x=0∑∞2x×(x+2×j−1)×P(x,i)
考虑与 g i , j + 1 g_{i,j+1} gi,j+1 发生联系,做差发现:
g i , j + 1 − g i , j = ∑ x = 0 ∞ x × ( x + 2 × j + 1 − x − 2 × j + 1 ) 2 × P ( x , i ) = ∑ x = 0 ∞ x × 2 2 × P ( x , i ) = f i ∴ g i , j = g i , j + 1 − f i . \begin{align}g_{i,j+1}-g_{i,j}=\sum_{x=0}^\infty\frac{x\times(x+2\times j+1 - x-2\times j+1)}{2}\times P(x,i)\\ = \sum_{x=0}^\infty \frac{x\times2}{2}\times P(x,i)= f_i\\ \therefore g_{i,j}=g_{i,j+1}-f_i. \end{align} gi,j+1−gi,j=x=0∑∞2x×(x+2×j+1−x−2×j+1)×P(x,i)=x=0∑∞2x×2×P(x,i)=fi∴gi,j=gi,j+1−fi.
化简该式子:
g i , j = g i , j + 1 × i n + g i + 1 , j + 1 × n − i n + j ⇔ g i , j = ( g i , j + f i ) × i n + ( g i + 1 , j + f i + 1 ) × n − i n + j ⇔ n × g i , j = i × ( g i , j + f i ) + ( g i + 1 , j + f i + 1 ) × ( n − i ) + n × j ⇔ n × g i , j = i × g i , j + i × f i + n × g i + 1 , j − i × g i + 1 , j + n × f i + 1 − i × f i + 1 + n × j ⇔ ( n − i ) × g i , j = ( n − i ) × g i + 1 , j + i × f i + ( n − i ) × f i + 1 + n × j ⇔ g i , j = g i + 1 , j + f i + 1 + i × f i + n × j n − i ⇔ g i , j = g i + 1 , j + f i + 1 + f i × i n − i + n × j n − i g_{i,j}=g_{i,j+1}\times \frac{i}{n}+g_{i+1,j+1}\times\frac{n-i}{n}+j\\ \begin{align} &\Leftrightarrow& g_{i,j}=(g_{i,j}+f_i)\times\frac{i}{n}+(g_{i+1,j}+f_{i+1})\times\frac{n-i}{n}+j\\ &\Leftrightarrow& n\times g_{i,j}=i\times(g_{i,j}+f_i)+(g_{i+1,j}+f_{i+1})\times(n-i)+n\times j\\ &\Leftrightarrow&n\times g_{i,j}=i\times g_{i,j}+i\times f_i+n\times g_{i+1,j}-i\times g_{i+1,j}+n\times f_{i+1}-i\times f_{i+1}+n\times j\\ &\Leftrightarrow& (n-i)\times g_{i,j}=(n-i)\times g_{i+1,j}+i\times f_i+(n-i)\times f_{i+1}+n\times j\\ &\Leftrightarrow& g_{i,j}=g_{i+1,j}+f_{i+1}+\frac{i\times f_i+n\times j}{n-i}\\ &\Leftrightarrow& g_{i,j}=g_{i+1,j}+f_{i+1}+f_i\times\frac{i}{n-i}+\frac{n\times j}{n-i} \end{align} gi,j=gi,j+1×ni+gi+1,j+1×nn−i+j⇔⇔⇔⇔⇔⇔gi,j=(gi,j+fi)×ni+(gi+1,j+fi+1)×nn−i+jn×gi,j=i×(gi,j+fi)+(gi+1,j+fi+1)×(n−i)+n×jn×gi,j=i×gi,j+i×fi+n×gi+1,j−i×gi+1,j+n×fi+1−i×fi+1+n×j(n−i)×gi,j=(n−i)×gi+1,j+i×fi+(n−i)×fi+1+n×jgi,j=gi+1,j+fi+1+n−ii×fi+n×jgi,j=gi+1,j+fi+1+fi×n−ii+n−in×j
显然这里的 j j j 对于转移是无用的,因为我们只需要知道 j = 1 j=1 j=1 的答案,所以说我们的转移如下:
g i = g i + 1 + f i + 1 + f i × i n − i + n n − i g_{i}=g_{i+1}+f_{i+1}+f_i\times\frac{i}{n-i}+\frac{n}{n-i} gi=gi+1+fi+1+fi×n−ii+n−in
于是我们用 O ( n + n ) O(n+n) O(n+n) 解决了这道题目。
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <iomanip>
#define N 10005
#define ld long double
using namespace std;
int n;
ld f[N],g[N];
int main(){cin >> n;for (int i = n - 1;i >= 0;i --) f[i] = f[i + 1] + 1.0 * n / (n - i);for (int i = n - 1;i >= 0;i --) g[i] = g[i + 1] + f[i + 1] + f[i] * 1.0 * i / (n - i) + 1.0 * n / (n - i);cout << fixed << setprecision(2) << g[0];return 0;
}