• 开学考试题4:book 书(概率期望dp)


    题目:

                      书

    Hazel有n本书,编号1为n到 ,叠成一堆。当她每次抽出一本书的时候,上方的书会因重力而下落,这本被取出的书则会被放置在书堆顶。

    每次有pi的概率抽取编号为i的书。她每次抽书所消耗的体力与这本书在这堆中是第几本成正比。具体地,抽取堆顶的书所耗费体力值为1 ,抽取第二本耗费体力值为2 ,以此类推。

    现在 想知道,在很久很久以后(可以认为几乎是无穷的),她每次抽书所耗费的体力的期望值是多少。

    最终的答案显然可以表示成a/b的形式,请输出a*(b^-1)模1e9+7的值。

    【输入格式】

    第一行一个整数n

    接下来n行,每行两个整数ai,bi,代表抽取第i本书的概率是ai/bi

    保证所有书的概率和等于1

    分析:

    通过抽书而改变的排列顺序,一共有n!种,当抽书的次数无限多时,每一种排列方式的概率相同。

    枚举排列方式来统计答案,复杂度很高,所以考虑每一本书对答案的贡献。

    ans=抽到这本书的概率 * 这本书的期望体力消耗。

    这本书的期望体力消耗=其他书放在它上面使它产生多1 的体力

    即 ∑ j:(1~n 且 j!=i)p [ j ] / ( p[ i ]+p[ j ])。(抽到这两本书的概率*先抽 j 的概率)//

    当然,即使没有书放在它上面,也要产生1的体力,所以要+1。

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define N 1005
    #define ri register int
    const ll mod=1e9+7;
    ll a[N],b[N],p[N];
    ll quick_pow(ll a,ll k)
    {
        ll ans=1;
        while(k){ if(k&1) ans=ans*a%mod; a=a*a%mod; k>>=1; }
        return ans;
    }
    int main()
    {
        freopen("book.in","r",stdin);
        freopen("book.out","w",stdout);
        int n;
        scanf("%d",&n);
        for(ri i=1;i<=n;++i) scanf("%lld%lld",&a[i],&b[i]),p[i]=a[i]*quick_pow(b[i],mod-2) %mod;
        ll ans=0;
        for(ri i=1;i<=n;++i){
            ll tmp=0;
            for(ri j=1;j<=n;++j)
            if(i!=j) tmp=( tmp+ p[j]*quick_pow(p[i]+p[j],mod-2) %mod ) %mod;
            ans=( ans+p[i]*(tmp+1)%mod )%mod;
        }
        printf("%lld
    ",ans);
    }
    /*
    2
    227494 333333
    105839 333333
    
    10
    159073 999999
    1493 142857
    3422 333333
    4945 37037
    2227 111111
    196276 999999
    190882 999999
    142721 999999
    34858 999999
    101914 999999
    */
    View Code
  • 相关阅读:
    OS-lab4
    OS-lab3
    OS-lab2
    OS-lab1
    OO第四单元总结
    OO第三单元总结
    OO第二单元总结
    HTTP_POST
    实习日志1(2020.7.27-2020.9.31)
    Web app ------ 从Servlet读取Json数据并显示,生成历史数据曲线图
  • 原文地址:https://www.cnblogs.com/mowanying/p/11529066.html
Copyright © 2020-2023  润新知