BZOJ 1426: 收集邮票 [DP 期望 平方]

传送门

题意:

有n种不同的邮票,皮皮想收集所有种类的邮票。唯一的收集方法是到同学凡凡那里购买,每次只能买一张,并且买到的邮票究竟是n种邮票中的哪一种是等概率的,概率均为1/n。但是由于凡凡也很喜欢邮票,所以皮皮购买第k张邮票需要支付k元钱。 现在皮皮手中没有邮票,皮皮想知道自己得到所有种类的邮票需要花费的钱数目的期望。


想了好几天了

一开始想求期望次数再套上等差数列,然后一直$WA$

其实应该再求长度平方的期望,就因为变量平方的期望想了好几天

非常感谢SD_le大爷的帮助

先说怎么求期望次数

$f[i]$表示已经有$i$种集齐$n$种的期望次数

$f[i]=f[i+1]+\frac{n}{n-i}$

推导:

设$p_i$为有$i$种再买到一种不同的需要几张,$Q=\frac{n-i}{n}$

$p_i=Q+(1-Q)Q+(1-Q)(1-Q)Q+...=\frac{1}{Q}$

其实这个结论看起来比较显然.....

然后设$g[i]$为变量平方的期望

我一直觉得$g[i]=g[i+1]+2*\frac{n}{n-i}*f[i+1]+\frac{n^2}{(n-i)^2}$,因为我感觉期望的关系就是变量的关系了

但不对,首先$g[i+1]=f[i+1]^2$一看就不能这么写

民科的想一下,期望的关系是一种加概率平均的关系,不能反映每个变量的关系

所以,请看这里http://www.cnblogs.com/ezyzy/p/6475861.html

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
typedef unsigned long long ll;
const int N=1e4+;
inline int read(){
char c=getchar();int x=,f=;
while(c<''||c>''){if(c=='-')f=-;c=getchar();}
while(c>=''&&c<=''){x=x*+c-'';c=getchar();}
return x*f;
}
int n;
double f[N],g[N];
int main(){
n=read();
for(int i=n-;i>=;i--){
f[i]=f[i+]+(double)n/(n-i);
g[i]=g[i+] + *f[i+] + 2.0*i/(n-i)*f[i] + (double)n/(n-i);
}
printf("%.2lf",(f[]+g[])/);
}
上一篇:[转]20位活跃在Github上的国内技术大牛


下一篇:Wireshark学习笔记——怎样高速抓取HTTP数据包