1. 程式人生 > >洛谷P4550 收集郵票(概率期望)

洛谷P4550 收集郵票(概率期望)

傳送門

 

神仙題啊……這思路到底是怎麼來的……

ps:本題是第$k$次買郵票需要$k$元,而不是買的郵票標號為$k$時花費$k$元

我們設$g[i]$表示現在有$i$張,要買到$n$張的期望張數,設$P(x,i)$表示買$x$次能從$i$張買到$n$張的概率,則有$$g[i]=\sum_{x=0}^\infty x\times P(x,i)$$

然後考慮一下遞推關係式,有$$g[i]=g[i+1]+\frac{n}{n-i},g[n]=0$$

於是就可以愉快的遞推了

然後設$f[i][j]$表示現在有$i$張郵票,下一張郵票要花$j$元,買到$n$張的期望花費。不難發現如下的遞推式$$f[i][j]=j+f[i][j+1]\times \frac{i}{n}+f[i+1][j+1]\times \frac{n-i}{i}$$

然而因為$j$可能是無限大,所以我們沒辦法簡單的遞推。

於是換一個角度思考,我們考慮在$f[i][j]$的情況下還需要買幾次才能夠買齊,則有$$f[i][j]=\sum_{x=0}^\infty (j+(j+1)+...+(j+x-1))\times P(x,i)$$

其中$x$表示列舉次數,小括號裡是$x$次購買所需的花費

繼續推$$f[i][j]=\sum_{x=0}^\infty \frac{x(2j+x-1)}{2} \times P(x,i)$$

然後把$j+1$帶進去,可以得出$$f[i][j+1]-f[i][j]=\sum_{x=0}^\infty x\times P(x,i)=g[i]$$

然後再考慮一下原來的遞推公式$$f[i][j]=j+f[i][j+1]\times \frac{i}{n}+f[i+1][j+1]\times \frac{n-i}{i}$$

$$f[i][j]=j+(f[i][j]+g[i])\times \frac{i}{n}+(f[i+1][j]+g[i+1])\times \frac{n-i}{i}$$

然後移項之後可得$$f[i][j]=\frac{(j+g[i]\times \frac{i}{n}+(f[i+1][j]+g[i+1])\times \frac{n-i}{i})\times n}{n-i}$$

然後考慮一下,因為答案是$f[1][0]$,所以所有$j$不等於$0$的情況對我們都沒有用,於是可以把第二維省略,只考慮$j=0$的情況

$$f[i]=\frac{(j+g[i]\times \frac{i}{n}+(f[i+1]+g[i+1])\times \frac{n-i}{i})\times n}{n-i}$$

邊界條件為$f[n]=0$

然後就可以直接遞推了

 1 //minamoto
 2 #include<cstdio>
 3 const int N=10005;
 4 double f[N],g[N],m;int n;
 5 int main(){
 6     scanf("%d",&n),f[n]=g[n]=0,m=n;
 7     for(int i=n-1;i>=0;--i) g[i]=g[i+1]+m/(m-i);
 8     for(int i=n-1;i>=0;--i)
 9     f[i]=((f[i+1]+g[i+1])*(m-i)/m+g[i]*i/m+1.0)*m/(m-i);
10     printf("%.2lf\n",f[0]);
11     return 0;
12 }