题目:
书
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 */