题目:
小张很多年过年都没有回家了,这次回家父母给他安排了很多个相亲的姑娘,有一个很长的名单,长度为N。父亲负责安排约会,每次随机的选择一个要相亲的对象,母亲负责记录哪些姑娘已经约会过了。直到和所有的姑娘都约会完一遍以后,这个浩大的相亲工程才会结束。这些天父母在吵架,他们之间不会有任何的言语沟通。所以父亲不知道哪些姑娘已经约会过了。因此下次约会的对象很可能是以前已经约会过的。如果小张要把所有的姑娘都约会一遍,那么平均需要约会多少个姑娘?
思路:
这是一道概率题,主要考查数学功底,推出公式后几行代码就可以搞定。如果你熟悉概率论中的“赠券收集问题“,这个问题就迎刃而解了。
- 计算期望值:
假设 T 是约会完所有N 个姑娘约会的次数, ti 是在约会了第 i−1 个姑娘后,再约会到第 i 个(以前没有约会过的)姑娘所花的次数,那么T 和 ti 都是随机变量。在约会了 i−1 个姑娘后,再约会一个新的姑娘的概率 pi=n−i+1n , 所以 ti 是几何分布,并且有期望值 1pi 。根据期望值的线性性质:
E(T)=====E(t1)+E(t2)+⋯+E(tn)1p1+1p2+⋯+1pnnn+nn−1+⋯+n1n(11+12+⋯+1n)nHn
其中 Hn 是调和数,根据其近似值可化为:
E(T)=nHn=nlnn+γn+12+o(1) , as n→∞ ,其中 γ≈0.5772156649 是欧拉-马歇罗常数。
C++代码如下:
#include <iostream>
#include <vector>
#include <numeric>
#include <limits>
#include <time.h>
using namespace std;
/*请完成下面这个函数,实现题目要求的功能*/
/*当然,你也可以不按照下面这个模板来作答,完全按照自己的想法来 ^-^ */
/******************************开始写代码******************************/
double date(int N) {
double H = 0;
for (int i = 1; i <= N; i++)
{
H += 1.0 / i;
}
return N * H;
}
/******************************结束写代码******************************/
int main() {
double res;
int N;
cin >> N;
res = date(N);
printf("%.4f", res);
return 0;
}