http://acm.hdu.edu.cn/showproblem.php?pid=4586
大致题意:有一个骰子有n个面,掷到每一个面的概率是相等的,每一个面上都有相应的钱数。其中当你掷到m个面之一时,你有多掷一次的机会。问最后所得钱数的期望。
思路:设投掷第一次的期望是p,那么第二次的期望是m/n*p,第三次的期望是 (m/n)^2*p......第N次的期望是(m/n)^(N-1)*p。
那么这些期望之和便是答案。之前也是想到这,但不知道如何处理无限的情况。当时脑卡了,这不是赤裸裸的等比数列吗?
设q = m/n,公比就是q,本题中等比数列之和为p*(1-q^N)/(1-q)。分三种情况讨论:当p为0时,输出0.00;当q等于1时,说明可以无限的投掷下去,输出inf;当q < 1时,N无穷大时,1-q^N区域1,那么原式变为p/(1-q)。
#include <stdio.h> #include <iostream> #include <map> #include <stack> #include <vector> #include <math.h> #include <string.h> #include <queue> #include <string> #include <stdlib.h> #include <algorithm> #define LL long long #define _LL __int64 #define eps 1e-8 #define PI acos(-1.0) using namespace std; int n,m; int vis[210]; int a[210]; int sum,cnt; double p,q; int main() { while(~scanf("%d",&n)) { sum = 0; cnt = 0; memset(vis,0,sizeof(vis)); for(int i = 1; i <= n; i++) { cin >> a[i]; sum += a[i]; } p = (sum*1.0)/n; scanf("%d",&m); int x; for(int i = 1; i <= m; i++) { cin >> x; if(vis[x]) continue; cnt++; vis[x] = 1; } q = (cnt*1.0)/n; if(fabs(p) < eps) cout << "0.00" << endl; else if(fabs(q-1) < eps) cout << "inf" << endl; else printf("%.2lf\n",p/(1-q)); } return 0; }
hdu 4586 (概率+期望),布布扣,bubuko.com
时间: 2024-10-20 23:48:37