题目链接:http://acm.sgu.ru/problem.php?contest=0&problem=495
题目大意:有N个盒子,里面都放着礼物,M个人依次去选择盒子,每人仅能选一次,如果里面有礼物则将礼物取出来,把空盒子放回原位,若没有礼物,则把空盒子放回原位。求礼物被拿走的个数的数学期望。
令 x[i] 代表第i个人拿到的礼物的个数,即值为0或1。
那么,N个人拿到的礼物的个数为 X = Sigma(X[i])。
因此 E[X] = E[Sigma(X[i])] = Sigma(E[X[i]])
其中,X[i]服从两点分布,即E[X[i]] = P(i)。
定义状态f[i]代表第i个人能够抓到礼物的概率,可以将样本空间划分为第i-1个人拿到了礼物和第i-1个人没拿到礼物。
因此有 P(i) = P(i|~i-1) + P(i|i-1) 即 f[i] = f[i-1]*(f[i-1]-1/n)+(1-f[i-1])*f[i-1]
化简得f[i] = f[i-1]*(1-1/n)。
进一步。。数学期望就可以用等比数列求和公式来做了。。。。。
有代码:
1 ///#pragma comment(linker, "/STACK:102400000,102400000") 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 #include <vector> 6 #include <map> 7 #include <set> 8 #include <bitset> 9 #include <cmath> 10 #include <numeric> 11 #include <iterator> 12 #include <iostream> 13 #include <cstdlib> 14 #include <functional> 15 #include <queue> 16 #include <stack> 17 #include <string> 18 #include <cctype> 19 using namespace std; 20 #define PB push_back 21 #define MP make_pair 22 #define SZ size() 23 #define ST begin() 24 #define ED end() 25 #define CLR clear() 26 #define ZERO(x) memset((x),0,sizeof(x)) 27 typedef long long LL; 28 typedef unsigned long long ULL; 29 typedef pair<int,int> PII; 30 const double EPS = 1e-8; 31 32 const int MAX_N = 100000+100; 33 34 double f[MAX_N]; 35 int N,M; 36 37 int main() { 38 while( ~scanf("%d%d",&N,&M) ) { 39 f[1] = 1.0; 40 double ans = 1.0; 41 for( int i=2;i<=M;i++ ){ 42 f[i] = (1.0-f[i-1])*f[i-1] + f[i-1]*( f[i-1]-1.0/N ); 43 ans += f[i]; 44 } 45 printf("%.11f\n",ans); 46 } 47 return 0; 48 }
浙公网安备 33010602011771号