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