彩票问题
一、简述
彩票问题就是概率问题,也就是说从一堆数字当中抽取几个数字(这里仅仅只说明不按顺序的抽取,只要抽中相应数字即可),这个问题又可以简化为纸牌抽取游戏,类似于小时候玩过的“找王八”,现在也好久没玩了。。。
二、数学阐述
还是从纸牌说起:如果有两套卡片,第一副卡片数字从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;
}
本文来自博客园,作者:FZLS,转载请注明原文链接:https://www.cnblogs.com/FZLS-/p/14837861.html

浙公网安备 33010602011771号