概率编程问题:计算Houin Kyoma击败Nomu的存活概率并解释示例
问题描述
在跨界奇幻宇宙中,Houin Kyoma正和怪物Nomu对战——Nomu能一击秒杀他。Kyoma可以暂停时间恰好M秒,每秒发动一次攻击:
- 普通攻击的攻击力是A,每次攻击会等额减少Nomu的生命值;
- 发动超级攻击的概率是 ( L = \frac{L1}{L2} ),超级攻击的攻击力是 ( A+C );
- Nomu初始生命值为H,生命值降到0或以下时死亡。
我们需要计算Kyoma成功杀死Nomu并存活的概率:
- 如果完全不可能杀死Nomu,输出
RIP; - 如果可能,输出最简分数形式 ( \frac{p1}{p2} )(要求 ( p1 \leq p2 ) 且两者的最大公约数为1)。
输入格式:
- 第一行是整数T,表示测试用例数;
- 每个测试用例包含空格分隔的整数:
A H L1 L2 M C
解题思路
先判断杀死Nomu的可能性,再逐步计算对应概率:
可能性判断
- 最小总伤害:M次全普通攻击,即 ( M \times A )。如果这个值≥H,Kyoma100%能杀死Nomu,概率为
1/1; - 最大总伤害:M次全超级攻击,即 ( M \times (A+C) )。如果这个值<H,无论怎么攻击都打不死,输出
RIP; - 介于两者之间时,需要计算至少需要多少次超级攻击才能让总伤害≥H,再计算对应概率。
- 最小总伤害:M次全普通攻击,即 ( M \times A )。如果这个值≥H,Kyoma100%能杀死Nomu,概率为
计算所需最少超级攻击次数k
设需要k次超级攻击,总伤害满足:
[
k \times (A+C) + (M - k) \times A \geq H
]
化简后得到:
[
k \times C \geq H - M \times A
]
k必须是非负整数,因此最小值是 ( \lceil \frac{H - M \times A}{C} \rceil )(若 ( H - M \times A \leq 0 ),说明全普通攻击就够了,k=0)。计算概率并化简
概率等于“恰好k次超级攻击”到“恰好M次超级攻击”的概率之和:- 恰好t次超级攻击的概率是 ( C(M, t) \times (\frac{L1}{L2})^t \times (\frac{L2-L1}{L2})^{M-t} ),其中 ( C(M,t) ) 是组合数(从M次攻击中选t次发动超级攻击的方式数);
- 将所有t≥k的概率相加得到总概率;
- 最后用最大公约数(GCD)将分子分母约分到最简形式。
示例推导(输入:10 33 7 10 3 2)
代入示例参数:A=10,H=33,L1=7,L2=10,M=3,C=2
步骤1:判断可能性
- 最小总伤害:( 3 \times 10 = 30 < 33 )(全普通攻击不够);
- 最大总伤害:( 3 \times (10+2) = 36 \geq 33 )(全超级攻击可以杀死Nomu);
因此存在成功的可能。
步骤2:计算最少需要的超级攻击次数k
代入公式:
[
k \times 2 \geq 33 - 3 \times 10 = 3
]
即 ( k \geq 1.5 ),k必须是整数,所以最小值是2——Kyoma至少需要发动2次超级攻击才能杀死Nomu。
步骤3:计算总概率
我们需要计算“恰好2次超级攻击”和“恰好3次超级攻击”的概率之和:
- 恰好2次超级攻击的概率
组合数 ( C(3,2) = 3 ),概率为:
[
3 \times (\frac{7}{10})^2 \times (\frac{3}{10})^1 = 3 \times \frac{49}{100} \times \frac{3}{10} = \frac{441}{1000}
] - 恰好3次超级攻击的概率
组合数 ( C(3,3) = 1 ),概率为:
[
1 \times (\frac{7}{10})^3 = \frac{343}{1000}
] - 总概率
两者相加:( \frac{441}{1000} + \frac{343}{1000} = \frac{784}{1000} )
步骤4:约分最简分数
计算784和1000的最大公约数:
- 784的因数:( 2^4 × 7^2 );
- 1000的因数:( 2^3 × 5^3 );
- 最大公约数是 ( 2^3 = 8 )。
分子分母同时除以8:
[
\frac{784 ÷ 8}{1000 ÷ 8} = \frac{98}{125}
]
这就是示例输出的结果。
代码实现思路(可选)
如果要写代码实现,核心步骤是:
- 遍历每个测试用例,先完成可能性判断;
- 计算最小需要的超级攻击次数k;
- 用整数存储分子分母(避免浮点数精度问题),累加所有符合条件的概率项;
- 调用GCD函数约分分子分母,输出结果。
注意:计算组合数时可以用递推或直接计算,Python的int类型天然支持大整数,无需担心溢出问题。
内容的提问来源于stack exchange,提问作者DKB

