GDKOI 2021 TG DAY2 游戏(概率 dp)(解析+代码)(本文读者绝对 rp +++++)
序
貌似是做的第一道概率 dp 的题目
还是蛮有意思的
题意
当前有 0 0 0 颗星,当持有星术为 i i i 时,有 p i p_i pi 的概率可以获得一颗星,否则扣除一颗星。问期望需要多少次对局能获得 n n n 颗星,输出答案 % p \%p %p , p = 998244353 p=998244353 p=998244353 。
解法
概率 dp 走起
我们设 f i f_i fi 表示从 i − 1 i-1 i−1 走到 i i i 的期望局数
回到题目,我们尝试推出转移方程:
如果成功,那么耗费步数 1 1 1
如果失败,那么将会掉到 i − 2 i-2 i−2,那么再回到 i i i 的概率就是 f i − 1 + f i f_{i-1}+f_i fi−1+fi ,要乘上失败的概率 ( 1 − p i ) (1-p_i) (1−pi)
那么转移为 f i = 1 + ( f i − 1 + f i ) ( 1 − p i ) f_i=1+(f_{i-1}+f_i)(1-p_i) fi=1+(fi−1+fi)(1−pi)
发现一个有趣的问题
为啥自己转移自己?
拆一下就好啦
f
i
=
f
i
−
1
(
1
−
p
i
)
+
1
p
i
f_i=\frac{f_{i-1}(1-p_i)+1}{p_i}
fi=pifi−1(1−pi)+1
依此递推即可。
Q:可是概率是个分数吖,肿么办?
A:众所周知, i i i 的逆元 i n v ( i ) inv(i) inv(i) 就是在 % p \% p %p 意义下, i i i 的倒数,因此,除以一个数也就等于乘以它的逆元。
Q:什么,逆元!? exgcd 不要啊!
A:这道题的模数 998244353 998244353 998244353 是一个质数,根据费马小定理,当模数为质数 p p p 时, i i i 的逆元就是 i p − 2 i^{p-2} ip−2 ,快速幂即可。
鉴于我们状态的含义,最后的答案是 a n s = ∑ i = 1 n f i ans=\sum_{i=1}^{n} f_i ans=∑i=1nfi
不要忘记取模吖
代码
#include<cstdio>
#define ll long long int
using namespace std;
const ll Md=998244353;
const int N=1e6;
ll a[N+10],b[N+10];
ll inv(ll x)
{
ll y=Md-2;
ll ans=1;
while(y)
{
if(y&1)
{
ans=(ans*x)%Md;
}
x=(x*x)%Md;
y>>=1;
}
return ans;
}
int main()
{
freopen("game.in","r",stdin);
freopen("game.out","w",stdout);
int n;
scanf("%d",&n);
ll ans=0,lst=0;
for(int i=1;i<=n;i++)
{
ll x,y;
scanf("%lld%lld",&x,&y);
ll t=inv(y),t1=(x*t)%Md,t2=((y-x)*t)%Md;
lst=(((lst*t2)%Md+1)%Md*inv(t1))%Md;
ans=(ans+lst)%Md;
}
printf("%lld",ans);
return 0;
}
拉拉票
大家多多支持,点赞关注加收藏哦
有什么不同的解法或者发现了什么纰漏欢迎评论区提出交流
谢谢💐