一个抽奖模型的求解
2013-06-19
问题描述:
有3组数,分别都是 [0-9] 10个数字,从中随机分别各选择1个数字,不分先后顺序,作为开奖结果。开奖结果设定后,从中随机分别各选择1个数字,不分先后顺序,作为抽奖结果。
如果3个数字与开奖结果完全匹配,则是一等奖;
如果2个数字与开奖结果匹配,则是二等奖;
如果1个数字与开奖结果匹配,则是三等奖;
如果没有任何数字与开奖结果匹配,则不中奖;
问:1. 开奖结果总共有多少种?
2. 一、二、三等奖的概率各是多少?
求解过程:
首选计算开奖结果有多少种。从3组 [0-9] 10个数字中各选1个数字,那么有10^3=1000种情况,但是这是有序的情况。这里不考虑顺序,所以对于567与765这样的情况,是一种结果。所以,为了方便处理,我们对开奖结果设定为ABC,A、B、C 3个数字非降序排列。通过进而计算出现开奖结果有多少种。
先考虑最直观的一种解法:不考虑非降序的情况,对1000中情况进行非降序处理,然后去重,统计个数即为开奖结果的数量。
程序如下:
#include <iostream> #include <string> #include <set> #include <algorithm> using namespace std; void foo(string& s, int n, char c = '0') { if (s.size() >= n) { return; } else { s = string(n-s.size(), c) + s; } } int main() { char s[3]; string str; set<string> ss; for (int i = 0; i != 100; ++i) { itoa(i, s, 10); str = s; foo(str, 3); sort(str.begin(), str.end()); ss.insert(str); } for (int i = 100; i != 1000; ++i) { itoa(i, s, 10); str = s; sort(str.begin(), str.end()); ss.insert(str); } cout << ss.size() << endl; system("PAUSE"); return 0; }
这样是处理了所有的1000个结果,对其排序并去重。有种更为笨拙的方法是,针对每个结果,去扫描前面是否已经出现过,不过这种原来和上面是一样的,只不过上面用了set时间复杂度为O(NlogN),如果逐个扫描的时间复杂度为O(N^2)。
这两种方法都不太好,考虑到开奖结果是不区分顺序的,所以对于567、576、657、675、756、765这六种结果都可以看做是一种结果567,我们对结果进行非降序处理。处理后的形式为:ABC,其中A<=B<=C。根据非降序的特性,我们可以得到一种更为快捷的方式来计算开奖结果的数量。程序如下:
//2.cpp #include <iostream> using namespace std; int main() { int total = 0; for (int A = 0; A != 10; ++A) { for (int B = A; B != 10; ++B) { for (int C = B; C != 10; ++C) { ++total; } } } cout << total << endl; system("PAUSE"); return 0; }
这种方法是根据非降序的特性得到的结果,时间复杂度为O(N)。
综上所述,我们知道开奖结果总结有220种结果。
那么,这220种结果有几种形式呢,注意,这里的220种是非降序处理后的。有以下四种形式:
AAA
AAB
ABB
ABC
其中A<B<C。
四种形式对应的数目分别为:
AAA:3个数字一样,所以共计有10种
AAB:9+8+7+…+1+0 = 45种
ABB:9+8+7+…+1+0 = 45种
ABC:220-10-45-45 = 120种
也可由程序计算而得:
//3.cpp #include <iostream> using namespace std; int main() { int total = 0; int aaa = 0; int aab = 0; int abb = 0; int abc = 0; for (int A = 0; A != 10; ++A) { for (int B = A; B != 10; ++B) { for (int C = B; C != 10; ++C) { if (A == B && B == C) { ++aaa; } else if (A == B && B < C) { ++aab; } else if (A < B && B == C) { ++abb; } else // if (A < B && B < C) { ++abc; } ++total; } } } cout << total << endl; cout << aaa << endl; cout << aab << endl; cout << abb << endl; cout << abc << endl; system("PAUSE"); return 0; }
综上所述,四种情况的种类数如下:
AAA |
10 |
AAB |
45 |
ABB |
45 |
ABC |
120 |
现在我们计算一等奖的概率,讨论一等奖的概率需要分为以上四种情况。
1) AAA
这种情况只有AAA这种形式,所以中一等奖的概率为 1/1000
2) AAB
这种情况有AAB、ABA、BAA三种形式,中一等奖的概率为3/1000
3) ABB
这种情况有ABB、BAB、BBA三种形式,中一等奖的概率为3/1000
4) ABC
这种情况有ABC、ACB、BAC、BCA、CAB、CBA六种形式,中一等奖的概率为6/1000
所以,根据全概率公式得到一等奖的概率为:
P(一等奖) = P(AAA)*P(一等奖|AAA) + P(AAB)*P(一等奖|AAB) + P(ABB)*P(一等奖|ABB) +
P(ABC)*P(一等奖|ABC)
= 10/1000*1/1000 + 135/1000*3/1000 + 135/1000*3/1000 + 720/1000*6/1000
= 0.00514
二等奖的概率:
1) AAA
中二等奖既是匹配2个数字,所以抽检的结果只能是AAX这种,其中X!=A,所以概率为3*9/1000=27/1000
2) AAB
a) AAA 这种情况有1种
b) AAX 这种情况有3*8种
c) ABB 这种情况有3种
d) ABX 这种情况有6*8种(X != A, X!= B)
所以,概率为76/1000
3) ABB
a) BBB 这种情况有1种
b) XBB 这种情况有3*8种
c) AAB 这种情况有3种
d) ABX 这种情况有6*8种
所以,概率为76/1000
4) ABC
a) ABA 这种情况有3种
b) ABB 这种情况有3种
c) ABX 这种情况有6*7种
d) ACA 这种情况有3种
e) ACC 这种情况有3种
f) ACX 这种情况有6*7种
g) BCB 这种情况有3种
h) BCC 这种情况有3种
i) BCX 这种情况有6*7种
所以,概率为144/1000
所以,根据全概率公式得到二等奖的概率为:
P(二等奖) = P(AAA)*P(二等奖|AAA) + P(AAB)*P(二等奖|AAB) + P(ABB)*P(二等奖|ABB) +
P(ABC)*P(二等奖|ABC)
= 10/1000*27/1000 + 135/1000*76/1000 + 135/1000*76/1000 +
720/1000*144/1000
= 0.12447
三等奖的概率:
1) AAA
a) AXX:3*9=27种情况
b) AXY:6*36=216种情况,或3*72=216种情况
所以,概率为243/1000
2) AAB
a) BBB:1种情况
b) AXX:3*8=24种情况
c) BBX:3*8=24种情况※
d) BXX:3*8=24种情况
e) AXY:6*28=168种情况,或3*56=168种情况
f) BXY:6*28=168种情况,或3*56=168种情况
所以, 概率为409/1000
3) ABB
a) AAA:1种情况
b) AAX:3*8=24种情况※
c) AXX:3*8=24种情况
d) BXX:3*8=24种情况
e) AXY:6*28=168种情况,或3*56=168种情况
f) BXY:6*28=168种情况,或3*56=168种情况
所以,概率为409/1000
4) ABC
a) AAA:1种情况
b) AAX:3*7=21种情况※
c) BBB:1种情况
d) BBX:3*7=21种情况※
e) CCC:1种情况
f) CCX:3*7=21种情况※
g) AXX:3*7=21种情况
h) BXX:3*7=21种情况
i) CXX:3*7=21种情况
j) AXY:6*21=126种情况,或3*42=126种情况
k) BXY:6*21=126种情况,或3*42=126种情况
l) CXY:6*21=126种情况,或3*42=126种情况
所以,概率为507/1000
所以,根据全概率公式得到三等奖的概率为:
P(三等奖) = P(AAA)*P(三等奖|AAA) + P(AAB)*P(三等奖|AAB) + P(ABB)*P(三等奖|ABB) +
P(ABC)*P(三等奖|ABC)
= 10/1000*243/1000 + 135/1000*409/1000 + 135/1000*409/1000 +
720/1000*507/1000
= 0.4779
不中奖的概率:
P(不中奖)= 1 – P(一等奖)– P(二等奖)– P(三等奖)
= 1 - 0.00514 - 0.12447 - 0.4779
= 0.39249
从四种情况讨论不中奖的概率:
1) AAA
a) XXX:9种情况
b) XXY:3*36=108种情况
c) XYY:3*36=108种情况
或者b、c合并:9*8*3=216种情况
d) XYZ:9*8*7=504种情况
所以,概率为729/1000,另一个角度为:9/10*9/10*9/10=729/1000
2) AAB
8/10*8/10*8/10=512/1000
a) XXX:8种情况
b) XXY:3*28=84种情况
c) XYY:3*28=84种情况
或者b、c合并:8*7*3=168种情况
d) XYZ:8*7*6=336种情况
所以,概率为512/1000
3) ABB
8/10*8/10*8/10=512/1000
a) XXX:8种情况
b) XXY:3*28=84种情况
c) XYY:3*28=84种情况
或者b、c合并:8*7*3=168种情况
d) XYZ:8*7*6=336种情况
所以,概率为512/1000
4) ABC
7/10*7/10*7/10=343/1000
a) XXX:7种情况
b) XXY:3*21=63种情况
c) XYY:3*21=63种情况
或者b、c合并:7*6*3=126种情况
d) XYZ:7*6*5=210种情况
所以,概率为343种情况
所以,根据全概率公式得到不中奖的概率为:
P(不中奖) = P(AAA)*P(不中奖|AAA) + P(AAB)*P(不中奖|AAB) + P(ABB)*P(不中奖|ABB) +
P(ABC)*P(不中奖|ABC)
= 10/1000*729/1000 + 135/1000*512/1000 + 135/1000*512/1000 +
720/1000*343/1000
= 0.39249
综上所述,针对未中奖的概率通过两种方法得到的概率是一致的。这也就证明了我们关于一、二、三等奖的计算是正确的。
奖项 |
概率 |
一等奖 |
0.00514 |
二等奖 |
0.12447 |
三等奖 |
0.4779 |
未中奖 |
0.39249 |
后记:下一步进一步讨论如下方面
1. 如何判断中奖,即如何判断匹配的数字数及具体匹配了哪些数字
2. 以上讨论的是3位的抽奖情况,针对N位的情况怎么办,针对N位的情况,如果得到一个开奖结果的汇总(递归实现?)