一个抽奖模型的求解ios
2013-06-19spa
问题描述:3d
有3组数,分别都是 [0-9] 10个数字,从中随机分别各选择1个数字,不分前后顺序,做为开奖结果。开奖结果设定后,从中随机分别各选择1个数字,不分前后顺序,做为抽奖结果。code
若是3个数字与开奖结果彻底匹配,则是一等奖;blog
若是2个数字与开奖结果匹配,则是二等奖;排序
若是1个数字与开奖结果匹配,则是三等奖;递归
若是没有任何数字与开奖结果匹配,则不中奖;ci
问:1. 开奖结果总共有多少种?string
2. 1、2、三等奖的几率各是多少?it
求解过程:
首选计算开奖结果有多少种。从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)。
这两种方法都不太好,考虑到开奖结果是不区分顺序的,因此对于56七、57六、65七、67五、75六、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
综上所述,针对未中奖的几率经过两种方法获得的几率是一致的。这也就证实了咱们关于1、2、三等奖的计算是正确的。
奖项 |
几率 |
一等奖 |
0.00514 |
二等奖 |
0.12447 |
三等奖 |
0.4779 |
未中奖 |
0.39249 |
后记:下一步进一步讨论以下方面
1. 如何判断中奖,即如何判断匹配的数字数及具体匹配了哪些数字
2. 以上讨论的是3位的抽奖状况,针对N位的状况怎么办,针对N位的状况,若是获得一个开奖结果的汇总(递归实现?)