题目链接:Click here
Solution:
本题直接推价格似乎很难,考虑先从购买次数入手
设购买次数(g(i))为当前有(i)种不同的邮票,要买到(n)种的期望购买次数
可以由期望的定义得到式子:(g(x)=sum_{i=0}^{+infty}P(i,x)),其中(P(i,x))为买(i)次从(x)种买到(n)种的概率
对于一个局面,记它可以转移到的局面集合为(to),则它的期望可以表示为
其中(P(v))表示从(v)局面转移到(u)局面的概率,(cost(v,u))表示从(v)转移到(u)局面的的代价
那么对于本题也可以如此转化:(g(x)=frac{x}{n}(g(x)+1)+frac{n-x}{n}(g(x+1)+1))
也很好理解,因为再抽一张卡,可能抽到已经抽到的,也可能抽到新的,而转移的代价都为1
显然,(g(n)=0),再把式子转化一下,就可以得到(g(x))的计算方式:
然后我们再考虑设(f(i,j))表示当前有(i)种邮票,下次购买要花(j)元时,买到(n)种的期望花费
我们知道购买要(j)元,结合题意,就能很好的推出(f(i,j))的转化方程:
我们考虑一下(f(i,j))的定义,便可以得出式子:
这里(P)的定义同上文(g(x))定义式中的(P),然后我们再考虑表示(f(i,j+1)),很简单,带入即可
考虑表示将(f(i,j+1))减去(f(i,j))可得:(f(i,j+1)-f(i,j)=sum_{u=0}uP(u,i))
可以发现它与前面的期望定义式是一样的,则我们得到式子:(f(i,j+1)=f(i,j)+g(i))
则我们可以把(f(i,j))表示一下:
事实上我们只需求出(f(0,1)),而在递推中可以发现(j)是没有变化的,则可以直接忽略(j)
Code:
#include<bits/stdc++.h>
using namespace std;
const int N=1e4+1;
int n;double u,f[N],g[N];
int read(){
int x=0,f=1;char ch=getchar();
while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
while(isdigit(ch)){x=x*10+ch-48;ch=getchar();}
return x*f;
}
int main(){
n=read();f[n]=g[n]=0;u=n;
for(int i=n-1;~i;i--) g[i]=g[i+1]+u/(u-i);
for(int i=n-1;~i;i--){
double x=i,y=n-i;
f[i]=f[i+1]+g[i+1]+x/y*g[i]+u/y;
}Pintf("%.2lf",f[0]);
return 0;
}
题外话:推的时候发现了另外一个式子:设(P(x))表示用(x)步刚好取到所有邮票的概率,则:
式子也很好理解,保证最后取到没取到的那种,再取完其它的种类,剩下的步数只要不取到最后那枚就行
则本题也可以这样求:
然后对这个式子求个通项就行了,不过我还不会求。。。