「BZOJ 1426」收集邮票
题目链接
\(Solution\)
我们首先转换一下问题:
假设我们进行了k轮得到了所有种类的邮票
则所花费用为:
\[(1+2+5+...+k)=\frac{(1+k)*k}{2}=\frac{k+k^2}{2}
\]
所以我们现在要求的就是\(\frac{k+k^2}{2}\)的期望
因为\(E(A+B)=E(A)+E(B)\)
所以\(E(k+k^2)=E(k)+E(k^2)\)
\(ps:\)平方的期望不等于期望的平方
所以我们要分别维护
设\(p1[i]\)为收集了\(i\)张邮票之后还要花费的次数的期望,\(p2[i]\)为收集了\(i\)张邮票之后还要花费的次数平方的期望
由于有\(\frac{i}{n}\)的概率拿到重复的,\(\frac{n-i}{n}\)的概率拿到不重复的。
可得\(p1\)的方程:
\[p1[i]=(p1[i]+1)*\frac{i}{n}+(p1[i+1]+1)*\frac{n-i}{n}
\]
将上方程可化简为:
\[p1[i]=p1[i+1]*\frac{n}{n-i}
\]
因为\(E((x+1)^2)=E(x^2+2x+1)=E(x^2)+E(2x)+E(1)=E(X^2)+2E(x)+1\)
\(p2\)的方程:
\[p2[i]=(p2[i]+2*p1[i]+1)*\frac{i}{n}+(p2[i+1]+p1[i+1]*2+1)*\frac{n-i}{n}
\]
化简为:
\[p2[i]=p2[i+1]+2*p1[i+1]+1+(2*p1[i]+1)*\frac{i}{n-i}
\]
最后答案为:
\[\frac{p1[0]+p2[0]}{2}
\]
\(Code\)
#include<bits/stdc++.h>
#define rg register
#define file(x) freopen(x".in","r",stdin);freopen(x".out","w",stdout);
using namespace std;
int read(){
int x=0,f=1;char c=getchar();
while(c<'0'||c>'9') f=(c=='-')?-1:1,c=getchar();
while(c>='0'&&c<='9') x=x*10+c-48,c=getchar();
return f*x;
}
double p1[10001],p2[10001];
int main(){
int n=read();
p2[n]=0;p1[n]=0;
for(int i=n-1;i>=0;i--)
p1[i]=p1[i+1]+n*1.0/(n-i),p2[i]=p2[i+1]+2*p1[i+1]+1+i*1.0/(n-i)*(2*p1[i]+1);
printf("%0.2lf",(p1[0]+p2[0])/2);
return 0;
}