[2016北京集训测试赛5]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;
}

 

转载于:https://www.cnblogs.com/coco-night/p/9640686.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值