多彩票组合赢取至少目标金额的概率计算方法咨询
计算多彩票单次购买后赢取至少指定金额的概率
问题分析
每个彩票独立购买一次,每个彩票有两种结果:以给定概率赢得对应奖金,或者不中奖(奖金0)。我们需要计算所有彩票的总奖金之和≥目标金额的概率。由于彩票数量最多可达40,暴力枚举所有2^40种结果完全不可行,因此**动态规划(DP)**是最优解法。
动态规划解法思路
维护一个概率分布字典,其中键是当前可能的总奖金金额,值是获得该金额的概率。初始状态为:总奖金0,概率1.0(未购买任何彩票时的状态)。
逐个处理每个彩票时,更新概率分布:
- 对于当前分布中的每个金额
s及其概率p:- 不中奖:总金额仍为
s,概率累加p * (1 - 彩票中奖概率) - 中奖:总金额变为
s + 彩票奖金,概率累加p * 彩票中奖概率
- 不中奖:总金额仍为
- 为优化空间和计算效率,当总金额≥目标值时,将这些状态合并为一个统一条目,避免后续不必要的状态拆分。
Python实现代码
def win_at_least(lottery_list, target_val=10): # 初始化概率分布:初始总奖金0,概率1.0 prob_dist = {0: 1.0} for prob, reward in lottery_list: new_dist = {} for current_sum, current_prob in prob_dist.items(): # 处理不中奖的情况 if current_sum in new_dist: new_dist[current_sum] += current_prob * (1 - prob) else: new_dist[current_sum] = current_prob * (1 - prob) # 处理中奖的情况 new_sum = current_sum + reward # 合并≥目标值的状态,减少状态数量 key = '>=target' if new_sum >= target_val else new_sum if key in new_dist: new_dist[key] += current_prob * prob else: new_dist[key] = current_prob * prob prob_dist = new_dist # 计算最终≥目标值的总概率 total_prob = prob_dist.get('>=target', 0.0) # 检查是否有未被合并的大额金额状态 for sum_val, p in prob_dist.items(): if isinstance(sum_val, int) and sum_val >= target_val: total_prob += p return round(total_prob, 6) # 保留6位小数便于查看 # 示例测试 lottery_list = [(0.5, 5), (0.4, 6), (0.3, 7)] print(win_at_least(lottery_list, target_val=10))
示例验证
对于给定示例,手动计算符合条件的组合概率总和为0.35,运行代码后输出结果与该值一致,验证了解法的正确性。
性能说明
通过合并≥目标值的状态,即使处理40个彩票,状态数也不会出现指数级增长(最多为目标值大小+1个状态),该方法在效率上完全满足需求。
内容的提问来源于stack exchange,提问作者Nick W
相关产品推荐
相关产品推荐

