此筆記為UVa 10056的題目詳解,包含解題思路、C++範例程式碼。

What is the Probability? (ZeroJudge e510.)

題目

機率一直是電腦演算法不可或缺的一部分。 在確定性算法無法在短時間內解決問題的地方,概率性算法已應運而生。 在這個問題上,我們不處理任何概率算法。我們將僅嘗試確定某個玩家的獲勝機率。
我們透過類似擲骰子的方式來玩這個遊戲 (他不像普通骰子一樣有六個面)。 如果某個特定事件發生在玩家擲骰子時 (例如獲得數字3,獲得綠色的一面或其他任何東西),則宣佈為獲勝者。
此遊戲可以有N個玩家。 第一個玩家將擲骰子,然後第二個玩家,最後是第N個玩家,再來是第一個玩家,依此類推。 當玩家獲得期望的結果時,宣佈為獲勝者,比賽停止。 您必須確定其中一名 (第i名) 的獲勝機率。

輸入 / 輸出說明

輸入說明 輸出說明
一開始有一個整數S (S ≤ 1000),表示接下來有多少組輸入。
接下來的S行。 每行包含一個整數N (N ≤ 1000),一個浮點數p,一個整數i。
N表示玩家數,p表示一次成功事件發生的機率,i (i ≤ N) 表示要確定獲勝機率的玩家的序列 (序列號碼從1到N)。
(如果成功事件代表獲得數字3,則p是在一次投擲的獲得數字3的機率)。
例如:一個正常骰子,獲得數字3的機率為1/6
輸入不會有不合理的 p 值。
對於每組輸入,輸出第i個玩家獲勝的機率。
機率精確到小數點後四位。

解題思路

記得考慮 p = 0 的情況,因為浮點數不一定準,所以我設為 p < 1e-9 就輸出 0.0000。 這題也同時要注意,不一定第一輪就會結束,因此要考慮無窮次數的情況。 第 i 人獲勝的機率就是: 前 i 個人輸、第 i 個人贏的機率 * 前面幾輪全輸的機率。
$P_i = ((1-p)^{i-1} \times p) \times \sum_{k = 0}^{\infty}((1-p)^n)^k - (1)$
利用等比級數公式:
$S_k = \frac{a_1(1-r^k)}{1-r}$
代入 $(1)$ 後得:
$P_i = ((1-p)^{i-1} \times p) \times \frac{1 \times (1-((1-p)^n)^\infty)}{1-(1-p)^n}$
因為 $1 - p < 1$,所以 $((1-p)^n)^\infty \approx 0$
$P_i \approx ((1-p)^{i-1} \times p) \times \frac{1}{1-(1-p)^n} \approx \frac{(1-p)^{i-1} \times p}{1-(1-p)^n}$
答案就是此公式的結果。
<另解> 這邊用條件機率的方式也算一下 $E$:第 i 個人獲勝的事件 $A$:第一輪第 i 個人獲勝的事件 $B$:第一輪其他人獲勝的事件 $F$:第一輪沒人獲勝的事件
$P(E)=P(E|A)P(A)+P(E|B)P(B)+P(E|F)P(F)$ 當 $P(A)$ 發生就代表第 $i$ 個人已經獲勝,那 $A$ 發生後 $E$ 發生的機率 $P(E|A)$ 一定是 1。 反之當 $P(B)$ 發生就代表其他人已經獲勝,那 $B$ 發生後 $E$ 發生的機率 $P(E|B)$ 一定是 0。 而當 $P(F)$ 發生後,就代表第一輪無人獲勝,那 $F$ 發生後 $E$ 發生的機率 $P(E|F)$ 其實也是 $P(E)$,因為他不影響第 $i$ 個人獲勝的機率。 由此可知: $P(E)=1 \times P(A)+0 \times P(B)+P(E)P(F)$ $\Rightarrow P(E)=(1-p)^{i-1} \times p+(1-p)^nP(E)$ $\Rightarrow (1-(1-p)^n)P(E)=(1-p)^{i-1} \times p$ $\Rightarrow P(E)=\frac{(1-p)^{i-1} \times p}{1-(1-p)^n}$ 答案是一樣的。

範例程式碼

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <bits/stdc++.h>
using namespace std;

int main()
{
int j, k;
int s, n, i;
double p, ans;

cin >> s;

for (j=0;j<s;j++) {
cin >> n >> p >> i;

if (p < 1e-9) { // 浮點數不一定準
cout << 0.0000 << endl;
continue;
}

ans = (p * pow((1-p), i-1)) / (1 - pow((1-p), n));

cout << fixed << setprecision(4) << ans << endl;
}

return 0;
}

運行結果

AC (1ms, 316KB)

查看更多資訊請至:https://www.tseng-school.com/