题目描述
有1-10数字的牌,可以有无限组 ,抽到每个数字等概率。规则是数字之和小于17可以再抽一次,等于或大于17而且小于21就赢了。如果抽到牌数字总和大于等于21就输了。最后求这个人赢的概率。
题目解析
-
有10个数,每次抽取的概率是1/10
-
也就是说以 1 / 10 1/10 1/10的概率来到a、b、c…这些累加和,当来到 a , b , c . . . . . . a,b,c...... a,b,c......之后获胜的概率分别是A、B、C、D…。那么整体获取概率是 A ∗ 1 / 10 + B ∗ 1 / 10..... A * 1/10 + B * 1/10 ..... A∗1/10+B∗1/10.....
-
可以用递归模拟这个过程
- 累加和是0的时候,要获得 1 , 2....10 1,2....10 1,2....10的概率
- 下层1的时候是有1的基础上再次抽到 1 , 2....10 1,2....10 1,2....10的概率,即累加和为 2 , 3.....11 2,3.....11 2,3.....11的概率
- 下层2的时候是有1的基础上再次抽到 1 , 2....10 1,2....10 1,2....10的概率,即累加和为 3 , 4.....13 3,4.....13 3,4.....13的概率
- …
class Solution {
// 当你来到cur这个累加和的时候,获胜概率是多少返回
double process(int cur){
if (cur >= 17 && cur < 21) {
return 1.0;
}
if (cur >= 21) {
return 0.0;
}
double w = 0.0;
for (int i = 1; i <= 10; i++) {
w += process(cur + i);
}
return w / 10;
}
public:
double f(){
return process(0);
}
};
扩展
- 面值为1~N的牌组成一组
- 每次你从组里等概率的抽出1~N中的一张
- 下次抽会换一个新的组,有无限组
- 当累加和<a时,你将一直抽牌
- 当累加和>=a且<b时,你将获胜
- 当累加和>=b时,你将失败
- 返回获胜的概率
class Solution {
// 当你来到cur这个累加和的时候,获胜概率是多少返回
double process(int cur, int N, int a, int b){
if (cur >= a && cur < b) {
return 1.0;
}
if (cur >= b) {
return 0.0;
}
double w = 0.0;
for (int i = 1; i <= N; i++) {
w += process(cur + i, N, a, b);
}
return w / N;
}
public:
// 面值为1~N的牌组成一组,
// 每次你从组里等概率的抽出1~N中的一张
// 下次抽会换一个新的组,有无限组
// 当累加和<a时,你将一直抽牌
// 当累加和>=a且<b时,你将获胜
// 当累加和>=b时,你将失败
double f(int N, int a, int b){
if (N < 1 || a >= b || a < 0 || b < 0) { //检查参数有效性
return 0.0;
}
if (b - a >= N) { //赢得区域大于牌数必赢!!!
return 1.0;
}
return process(0, N, a, b);
}
};