题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4586
这个题目应该算是一题比较简单的题目,简单在于精度要求就两位,而且还有Special Judge
我的思想是近似模拟的思想,每次仍骰子只有两种情况(特殊极端情况不考虑),要么是中奖(再来一次),要么是不中奖
那么我们可以将这两部分合并,求出两边平均的钱,然后求两边出现的概率,然后每次分两中情况,显然能写出一个类似递归的
式子(见程序中的while循环)来计算,知道子式子达到一定小的时候结束,就能得到这个题目的最终答案!
#include <iostream>
#include <string.h>
#include <algorithm>
#include <stdio.h>
using namespace std;
#define maxn 500
double rec[maxn];
double yes,no,total;//yes表示中奖,no表示没中奖
int n,m;
int main(){
int i,j,k;
double temp,p,ans,org;
while(scanf("%d",&n)!=EOF){
total=yes=no=0;
for(i=0;i<n;i++){
scanf("%lf",&rec[i]);
total+=rec[i];
}
scanf("%d",&m);
for(i=0;i<m;i++){
scanf("%d",&k);
yes+=rec[k-1];
}
if(total==0){ printf("0.00\n");continue;}
if(m>=n){
printf("inf\n");
continue;
}
if(m==0){ printf("%.2f\n",total/n);continue;}
no=total-yes;
yes/=m,no/=(n-m);
p=double(m)/n;//p表示选中奖的概率
org=p;
ans=no*(1-p)+yes*p;
temp=ans;
while(temp > 1e-6){
temp=p*(no*(1-org)+yes*org);
ans+=temp;
p*=org;
}
printf("%.2f\n",ans);
}
return 0;
}