官方題解:
補充這個dp轉移的 概率係數 是如何求出的:
由於人數是無限的,題目告訴我們隨機抽取一個號碼的概率是 ,實際上是告訴我們每個位置分配的概率是等可能的。
枚舉 A國人坐在第 i 個位置進行轉移,要求出他是A國人並且他坐在第 i 個位置的概率:注意這實際上是一個條件概率,他坐在第 i 個位置上是在他已經就坐這件事已經發生的基礎上發生的。
爲什麼這裏要用條件概率來進行轉移呢?
對於這題 dp 的決策,枚舉的轉移點是 :第一個坐下的人,他坐下的位置和他的國家
,而不是某個到來的人他坐下的位置和他的國家,因爲這個到來的人不一定會坐下(例如他是A國人他就不會坐在 1 和 n 這個位置)這種情況是無法轉移的,無法轉移就表明這個 有概率無解,這顯然不合理。
假設人數不是無限的,那麼有人就坐這件事就不是一定發生,對於沒有就坐的情況 dp[k] 不能由任何決策點轉移得到,因此dp[k] 可能是無解的。(這也是給出人數無限的意義)
因此,對於每個枚舉的轉移點,例如第一個坐下的人,他坐在第 i 個位置,並且他是A國人,需要求出一個概率 :P(他是A國人,並且他坐在第 i 個位置 | 有人就坐)
令 事件TA 表示:有人就坐, 事件 B1:他是A國人,事件B2:他是B國人。
假設當前枚舉的轉移點是:第一個坐下的人,他坐在第 i 個位置,並且他是 A 國人:先求出 P(B1 | A):坐下的這個人是A國人的概率,再除以 就得到坐下的這個人是 A國人,並且他坐在第 i 個位置的概率(因爲在就坐已經發生的條件下,A 國人就坐這件事 樣本空間有 n - 2 個位置
,每一個位置都是等可能的,因此每一個位置坐下的概率是 )
,在這個樣本空間中,事件 {B1,B2} 是一個完備事件組,考慮用貝葉斯公式得到這個概率值:
容易得出: , ,
可以計算得到:
同理可以得到:
代碼:
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e6 + 10;
typedef long long ll;
const int mod = 998244353;
ll n,p,q;
ll dp[maxn],sum[maxn];
ll fpow(ll a,ll b) {
ll r = 1;
while (b) {
if (b & 1) r = 1ll * r * a % mod;
b >>= 1;
a = 1ll * a * a % mod;
}
return r;
}
int main() {
scanf("%lld%lld%lld",&n,&p,&q);
dp[0] = dp[1] = dp[2] = 0;
if (p) dp[3] = dp[4] = 1;
for (int i = 1; i <= 4; i++)
sum[i] = sum[i - 1] + dp[i];
for (int i = 5; i <= n; i++) {
dp[i] = (2 * sum[i - 2] * p % mod + 2 * sum[i - 3] * q % mod) % mod;
ll t = (1ll * (i - 2) * p % mod + 1ll * (i - 4) * q % mod) % mod;
dp[i] = (dp[i] * fpow(t,mod - 2) + 1) % mod;
sum[i] = (sum[i - 1] + dp[i]) % mod;
}
printf("%lld\n",dp[n - 1] + 1);
}