码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2018-09-13 16:17:36      阅读:207      评论:0      收藏:0      [点我收藏+]

标签:pac   rip   html   name   一个   scan   测试   string   ima   

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]

标签:pac   rip   html   name   一个   scan   测试   string   ima   

原文地址:https://www.cnblogs.com/coco-night/p/9640686.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!