D e s c r i p t i o n \mathcal{Description} Description
有
n
n
n 堆石子,依次编号为
1
,
2
,
…
,
n
1, 2,\ldots , n
1,2,…,n,其中第
i
i
i 堆有
a
i
a_i
ai 颗石子
你每次等概率随机选择一颗石子,并取完它所在的那一堆石子
求第
1
1
1 堆石子被取走的时间的期望
n ≤ 1 0 5 , a i ≤ 1 0 9 n\leq 10^5,a_i\leq 10^9 n≤105,ai≤109
S o l u t i o n \mathcal{Solution} Solution
这题不是很难,然而并不是考虑
D
P
DP
DP,用的比较巧妙的方法
考虑期望的线性性,设
p
i
p_i
pi表示第
i
i
i堆石子在第一堆石子前
若第
i
i
i堆石子在第
1
1
1堆石子前被取出来,那么就会多
1
1
1次取走操作
换成期望就是
E
=
∑
i
=
2
n
p
i
∗
1
E=\sum\limits_{i=2}^np_i*1
E=i=2∑npi∗1
现在的问题就是求
p
i
p_i
pi了
考虑第
i
i
i堆石子在第
1
1
1堆石子之前被取走
假设现在有
t
o
t
tot
tot个石子,那么取走
i
i
i的概率是
a
i
t
o
t
\dfrac{a_i}{tot}
totai,取走
1
1
1的概率是
a
1
t
o
t
\dfrac{a_1}{tot}
tota1
无论
t
o
t
tot
tot的值是什么,第
i
i
i堆石子比第
1
1
1堆石子先被取走的概率都是
a
i
a
i
+
a
1
\dfrac{a_i}{a_i+a_1}
ai+a1ai
于是这道题就解决了
C o d e \mathcal{Code} Code
/*******************************
Author:Morning_Glory
LANG:C++
Created Time:2019年11月07日 星期四 20时01分34秒
*******************************/
#include <cstdio>
#include <fstream>
using namespace std;
const int maxn = 100005;
int n,x;
double ans;
int main()
{
scanf("%d%d",&n,&x);
for (int i=2;i<=n;++i){
int p;
scanf("%d",&p);
ans+=1.0*p/(x+p);
}
ans+=1;
printf("%.10lf\n",ans);
return 0;
}
如有哪里讲得不是很明白或是有错误,欢迎指正
如您喜欢的话不妨点个赞收藏一下吧