P4550 收集邮票
P4550 收集邮票 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
一种可能更加自然的推导
求出ans后直接\(\frac{ans(ans+1)}{2}\)不对的原因在于,这个式子算的是期望的平方,而我们需要求的是平方的期望,二者不等价。所以我们考虑如何去算平方的期望
令\(x_i\)表示已经得到了i种邮票,得到全部n种邮票所需要的次数,注意这里的\(x_i\)是一个随机变量
于是我们有转移式:
\[\begin{align}
& E(x_i)=\frac{i}{n}E(x_i+1)+\frac{n-i}{n}E(x_{i+1}+1) \\
& E(x_i^2)=\frac{i}{n}E((x_i+1)^2)+\frac{n-i}{n}E((x_{i+1}+1)^2)
\end{align}
\]
对二者分别整理即可得到期望的递推式,和平方的期望的递推式:
\[\begin{align}
& E(x_i)=E(x_{i+1})+\frac{n}{n-i} \\
& E(x_i^2)=E(x_{i+1}^2)+2E(x_{i+1})+\frac{2i}{n-i}E(x_i)+\frac{n}{n-i}
\end{align}
\]
答案为\(E(\frac{x_0(x_0+1)}{2})=\frac{E(x_0^2)+E(x_0)}{2}\)
#include<bits/stdc++.h>
#define db double
using namespace std;
const int N=1e4+10;
int n;
db ex[N],ex2[N];
int main()
{
// freopen("1.in","r",stdin);
scanf("%d",&n);
for(int i=n-1;i>=0;--i)
{
ex[i]=ex[i+1]+(db)n/(n-i);
ex2[i]=ex2[i+1]+2*ex[i+1]+(db)2*i/(n-i)*ex[i]+(db)n/(n-i);
}
printf("%.2lf\n",(ex2[0]+ex[0])/2);
return 0;
}