彩票问题

一、简述

彩票问题就是概率问题,也就是说从一堆数字当中抽取几个数字(这里仅仅只说明不按顺序的抽取,只要抽中相应数字即可),这个问题又可以简化为纸牌抽取游戏,类似于小时候玩过的“找王八”,现在也好久没玩了。。。

二、数学阐述

还是从纸牌说起:如果有两套卡片,第一副卡片数字从1-47,抽五张;第二幅卡片数字从1-27,抽一张,总共抽六张;那么你觉得抽中的概率你觉得有多大呢?

首先,从47张卡片中抽五张,而成功抽中的概率为1/R,则R的计算公式为:

R1=(47* 46* 45* 44* 43)/(5* 4* 3* 2* 1)

选择五个数时,分母为前五个数的乘积或者5的阶乘,分子也是5个连续整数的乘积,从47开始,依次减一

依次而言,第二幅卡片的概率一样如此,就暂定为R2;而总的概率R=R1* R2;

三、C++实现思路

根据上面的公式推广可以得到:如果从number个数中选取picks个数,则分母是picks的阶乘,分子为从number开始向前的picks个整数的乘积,因此可以用for循环来调用:

long double result =0.0
for(n = numbers, p = picks; p > 0; p--, n --)
  {
    result = result * n / p;
  }

for循环第一次运行的结果为:result = 1.0 * 47 / 5;

for循环第一次运行的结果为:result = (47 / 5) * 46 / 4;

是不是跟上面的公式一模一样?

而且这样得到的乘积更为准确,当数字很大时,这种交替乘除运算的策略可以防止中间结果超出最大的浮点数

四、完整测试代码

#include<iostream>
using nmaespace std;
long double probability(unsigned number, unsigned pick)
{
  long double result = 1.0;
  long double n = 0.0;
  unsigned p = 0;
  for (n = number, p = pick; p > 0; n--, p--)
  {
    result = result * n / p;
  }
  return result;
}

int main()
{
  const unsigned F1 = 47;
  const unsigned F2 = 27;

  cout << "你有" << probability(F1, 5) * probability(F2, 1) << "的几率赢!" << endl;
  return 0;
}
posted @ 2021-06-01 16:43  FZLS  阅读(306)  评论(0)    收藏  举报