【概率与期望】流星雨

链接:https://ac.nowcoder.com/acm/contest/368/C
来源:牛客网

在这里插入图片描述


 题目比较简单,但因为比较典型所以记录一下。
 另外,这种题一定要分清事件的概率,否则容易全盘皆错。
 这题中,某一天是否发生流星雨的概率,不仅和当天有关,还和之前的情况有关。假设这个事件发生的概率为 d p [ i ] dp[i] dp[i],则 d p [ i ] = d p [ i − 1 ] ∗ ( p i + P ) + ( 1 − d p [ i − 1 ] ) ∗ p i = P ∗ d p [ i − 1 ] + p i dp[i]=dp[i-1]*(p_i+P)+(1-dp[i-1])*p_i=P*dp[i-1]+p_i dp[i]=dp[i1](pi+P)+(1dp[i1])pi=Pdp[i1]+pi,于是可以递推。
 我后来又设了数组s来求出某一天是否发生流星雨的概率的条件下到这天的流星数期望,企图递推求出答案,可行,但是后来发现没有必要。因为数学期望具有可加性,无论两个事件是否独立,所以直接有 a n s = ∑ d p [ i ] ∗ w [ i ] ans=\sum dp[i]*w[i] ans=dp[i]w[i]

#include <cstdio>
#include <algorithm>
#define mo 1000000007

using namespace std;
using LL=long long;

struct frac     //这里也可以不用定义frac类,直接用一个整数=分子*分母的逆元来表示分数,代码会短很多,而效率会稍微差一些
{
    int x,y;

    frac(int x=0, int y=0):x(x),y(y){}

    frac(LL x, LL y):x(int(x)),y(int(y)){}

    frac operator+(const frac &t) const
    {
        return (frac){((LL)x*t.y+(LL)t.x*y)%mo,(LL)y*t.y%mo};
    }

    frac operator-(const frac &t) const
    {
        return (frac){((LL)x*t.y-(LL)t.x*y%mo)%mo,(LL)y*t.y%mo};
    }

    frac operator*(const frac &t) const
    {
        return (frac){(LL)x*t.x%mo,(LL)y*t.y%mo};
    }

    frac operator/(const frac &t) const
    {
        return (frac){(LL)x*t.y%mo,(LL)y*t.x%mo};
    }
}one(1,1),dp[100005],s[100005][2],w[100005],P,p[100005],ans;

int n;

int quick_power(int x, int y)
{
    int res=1,base=x;
    while(y)
    {
        if(y&1)
            res=(LL)res*base%mo;
        base=(LL)base*base%mo;
        y>>=1;
    }
    return res;
}

int main()
{
    scanf("%d%d%d",&n,&P.x,&P.y);
    for(int i=1;i<=n;i++)
        scanf("%d",&w[i].x),w[i].y=1;
    for(int i=1;i<=n;i++)
        scanf("%d%d",&p[i].x,&p[i].y);
    dp[1]=p[1];
    for(int i=2;i<=n;i++)
        dp[i]=P*dp[i-1]+p[i];
    //s[1][0]=(frac){0,1};
    //s[1][1]=w[1];
    ans=(frac){0,1};
    for(int i=1;i<=n;i++)
    {
        ans=ans+dp[i]*w[i];
        //s[i][1]=w[i]+((s[i-1][1])*(p[i]+P)*dp[i-1]+(s[i-1][0])*p[i]*(one-dp[i-1]))/dp[i];原先的思路,s[i][1]表示第i步发生流星雨时的期望总数
        //s[i][0]=(s[i-1][1]*(one-p[i]-P)*dp[i-1]+s[i-1][0]*(one-p[i])*(one-dp[i-1]))/(one-dp[i]);原先的思路,s[i][0]表示第i步不发生流星雨时的期望总数
    }
    //ans=s[n][1]*dp[n]+s[n][0]*(one-dp[n]);
    printf("%lld",(LL)ans.x*quick_power(ans.y,mo-2)%mo);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值