[2016北京集训测试赛]azelso-[概率/期望dp]

Posted coco-night

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[2016北京集训测试赛]azelso-[概率/期望dp]相关的知识,希望对你有一定的参考价值。

Description

技术分享图片

Solution

感谢大佬的博客https://www.cnblogs.com/ywwyww/p/8511141.html

定义dp[i]为[p[i],p[i+1])的期望经过次数,f[i]为处理完事件i后不会再回到i点或以前,直接到终点的概率。

则$dp[i]=1+(1-f[i])+(1-f[i])^{2}+......=frac{1}{f[i]}$

设事件i+1的胜率为k。

1:下一个事件是敌人,则f[i]=kf[i+1],即$dp[i]=frac{dp[i+1]}{k}$。

2:下一个事件是旗子,则$f[i]=f[i+1](1+k(1-f[i+1])+k^{2}(1-f[i+1]^{2}+...)=frac{f[i+1]}{1-k+kf[i+1]}$

把f替换为dp得$dp[i]=(1-k)dp[i+1]+k$

Code

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
const int mod=1e9+7;
typedef long long ll;
ll ksm(ll x,ll k)
{
    ll re=1;
    while (k)
    {
        if (k&1) re=re*x%mod;
        k>>=1;
        x=x*x%mod;
    }
    return re;
}
ll h,n;
ll p[100010],a[100010],b[100010];char c[100010][2];
ll dp[100010],ans=0;
int main()
{
    scanf("%lld%lld",&h,&n);
    for (int i=1;i<=n;i++)
    {
        scanf("%s%lld%lld%lld",c[i],&p[i],&a[i],&b[i]);
        a[i]=a[i]*ksm(b[i],mod-2)%mod;
    }
    dp[n]=1;
    for (int i=n;i;i--) 
    if (c[i][0]==X) dp[i-1]=dp[i]*ksm(a[i],mod-2)%mod;
    else dp[i-1]=((1-a[i]+mod)%mod*dp[i]%mod+a[i])%mod;
    p[n+1]=h;
    for (int i=0;i<=n;i++) ans=(ans+(p[i+1]-p[i])%mod*dp[i]%mod)%mod;
    cout<<ans;
}

 

以上是关于[2016北京集训测试赛]azelso-[概率/期望dp]的主要内容,如果未能解决你的问题,请参考以下文章

xsy1528azelso - 概率期望dp

2016北京集训测试赛(十七)- 小结

2016北京集训测试赛river

2016北京集训测试赛直径

2016北京集训测试赛 crash的数列

2016北京集训测试赛自动机 (思考题)