关于此题[ABC298E] Unfair Sugoroku 概率DP的一些总结
传送门
题目大意:两个人小T和小A分别从A点和B点开始,分别等概率地每次可以往后走
难以想到如何设计状态,由于我们同时要对小T和小A的位置进行维护,所以应该考虑将其分别设为同一个数组的两维来进行维护。我们设
我们将两人分别往后走看作一个一个回合,在每个回合中小T先走,不管小T是否走到N后小A都也往后走。于是想到可以用当前状态来更新后面的状态。
而对于当前
合并起来看
又由于要求逆元,分母应该为
所以我们在DP的时候就对于每一个
还要注意的是,最后累计求概率的时候,我们应该求
#include<bits/stdc++.h>
using namespace std;
const long long mod = 998244353;
long long t,ans;
const long long N = 2e5 + 10;
long long n,a,b,p,q;
long long f[110][110];
long long quickMul(long long x,long long k) {
if(k == 1) return x;
if(k == 0) return 1;
long long tmp = quickMul(x,k/2);
tmp = (tmp * tmp) % mod;
if(k % 2) tmp = (tmp * x) % mod;
return tmp;
}
void solve() {
cin >> n >> a >> b >> p >> q;
f[a][b] = 1;
for(long long i = a;i <= n - 1;i++) {
for(long long j = b;j <= n - 1;j++) {
for(long long k1 = 1;k1 <= p;k1++) {
for(long long k2 = 1;k2 <= q;k2++) {
f[min(n,i + k1)][min(n,j + k2)] = (f[min(n,i + k1)][min(n,j + k2)] + f[i][j] * quickMul(p * q,mod - 2) % mod) % mod;
}
}
}
}
for(long long i = b;i <= n;i++)
ans += f[n][i],ans %= mod;
cout << ans;
}
signed main() {
ios::sync_with_stdio(0);
cin.tie(0);cout.tie(0);
t = 1;
while(t--) solve();
return 0;
}
分类:
做题总结