知乎上看到一个有意思的问题,自己求解了一下
1、蒙特卡洛求解法,模拟次数1000000次。
思路很简单:相当于有1000000人,每人每次随机一个星座谈恋爱,把每个人集齐12个星座所需要随机的次数加起来,再除以总人数就是平均数了。
代码如下
#include <iostream>
#include <ctime>
using namespace std;
void main()
{
srand(unsigned(time(NULL)));
int total = 1000000;
bool star[12];
int *sum = new int[total];
for (int i = 0; i < total; i++)
{
int j = 0;
while (j < 12)
{
star[j] = false;
j++;
}
int k = 0, l = 0;
int m = 0;
while (1)
{
m++;
star[rand() % 12] = true;
j = 0; l = 0;
while (j < 12)
{
if (star[j])
{
l++;
}
j++;
}
if (l == 12)
{
break;
}
}
sum[i] = m;
}
int i = 0;
int totalman = 0;
while (i<total)
{
totalman += sum[i];
i++;
}
cout << "Average:" << 1.0*totalman / total << endl;
}
2、其实数学上就是赠券收集问题,类似的题目比如集齐108将需要吃多少包小浣熊?
思路是:集第一个星座的概率是1,所需要的人数为1;集第2个星座的概率是11/12,所需要的平均人数就是12/11;同理,集第3个星座所需要的平均人数是12/10.....最后集齐12星座总的平均人数就是:
12/12+12/11+12/10+12/9+.....+12/1 = 12×(1/12+1/11+....+1)
代码如下
i = 12;
while (i>0)
{
total1 += 1.0 / i;
i--;
}
total1 *= 12;
cout << "Average2:" << total1 << endl;
两次结果如下:
可见平均得谈38个啊,哈哈哈哈