​也许更好的阅读体验​

有 n nn 堆石子,依次编号为 1 , 2 , … , n 1, 2,\ldots , n1,2,…,n,其中第 i ii 堆有 a i a_ia i 颗石子 你每次等概率随机选择一颗石子,并取完它所在的那一堆石子 求第 1 11 堆石子被取走的时间的期望

n≤105,ai≤109

S o l u t i o n

这题不是很难,然而并不是考虑 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=2npi1

现在的问题就是求 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 C o d o \mathcal{Code} edCode

/*******************************
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;
}