题意:
给定一个n面的筛子,每次扔筛子每个面朝上的概率都是相同的,每面都有其相应的分数,现在我们可以扔一次,扔到面朝上的分数为我们所得,另还有m(<=m)个特殊的面,扔到此面朝上不仅可以得到分数,还能获得再扔一次的机会,求我们最终获得分数的期望,如果无限大,输出inf。
思路:
可以将所有面转化为两个面:能继续扔,停止扔。如果n==m,那么如果筛子的任意一面>0,那么就是inf,如果全为0,则还是0。其它情况模拟停止扔的次数即可,一直到次数很大时再扔所得的期望分数小于eps。
代码:
#include <bits/stdc++.h>
using namespace std;
const double eps = 1e-9;
const int up = 1e7;
int a[205];
int n, m;
int main()
{
while(~scanf("%d", &n))
{
int flag = 0;
double sumq = 0, sump = 0;
for(int i = 1; i <= n; i++)
{
scanf("%d", &a[i]);
sumq += a[i];
if(a[i] > 0) flag = 1;
}
scanf("%d", &m);
for(int i = 1; i <= m; i++)
{
int id;
scanf("%d", &id);
sump += a[id];
}
if(m == n)
{
if(flag) puts("inf");
else puts("0");
continue;
}
double y = (sumq-sump)/(n-m);
if(m == 0)
{
printf("%.2f\n", y);
continue;
}
double x = sump/m;
double p = 1.0*m/n;
double pi = 1, ans = 0;
for(int i = 1; i <= up; i++)
{
ans += pi*(1-p)*((i-1)*x+y);
pi *= p;
if(pi*(1-p)*((i-1)*x+y) < eps) break;
}
printf("%.2f\n", ans+eps);
}
return 0;
}
继续加油~