大家都很强, 可与之共勉。
收集邮票
Time Limit: 1 Sec Memory Limit: 162 MB
Description
有n种不同的邮票,皮皮想收集所有种类的邮票。唯一的收集方法是到同学凡凡那里购买,每次只能买一张,并且买到的邮票究竟是n种邮票中的哪一种是等概率的,概率均为1/n。但是由于凡凡也很喜欢邮票,所以皮皮购买第k张邮票需要支付k元钱。 现在皮皮手中没有邮票,皮皮想知道自己得到所有种类的邮票需要花费的钱数目的期望。
Input
一行,一个数字N N<=10000
Output
要付出多少钱. 保留二位小数
Sample Input
3
Sample Output
21.25
LINK
三行代码秒杀一切
你可知道这道题是多么难推。
题意很清楚
如何求?
第一次见概率题这么做的…好厉害
首先我们定义
g[i]
表示现在有
i
张,要买到
定义
P(x,i)
为买
x
次能从
那么可以得到:
那么就有:
得到 g[i]=g[i+1]+nn−i ,且知道 g[n]=0
那么我们设
f[i][j]
表示还现在有
i
张,下一张是
显然
所以转移显然:
但是 f[i][j] 是的递推是无穷大的,所以不能直接递推,考虑它的一些性质:
显然是个等差数列求和,所以可以得到:
然后我们作差 f[i][j+1]−f[i][j] 得到:
所以我们就可以对开始时 f[i][j] 这个式子进行化简,得到:
然后我们发现
j
这一维其实是无效的,我们只需要知道
然后我们就可以线性时间得到答案了。
# include <cstdio>
double g [10005], f [10005] ;
int main ( ) {
int n ;
scanf ( "%d", & n ) ;
for ( int i = n - 1 ; i >= 0 ; -- i ) g [i] = g [i + 1] + 1.0 * n / ( n - i ) ;
for ( int i = n - 1 ; i >= 0 ; -- i ) f [i] = f [i + 1] + g [i + 1] + g [i] * 1.0 * i / ( n - i ) + 1.0 * n / ( n - i ) ;
printf ( "%.2lf", f [0] ) ;
}