HDu 4586(確率+期待)


http://acm.hdu.edu.cn/showproblem.php?pid=4586
サイコロにはn面があり、各面に投げる確率は等しく、各面には相応の金額がある.その中でm面の1つを投げると、もう1回投げる機会があります.最後に得た金額の期待を聞く.
構想:投げ1回目の期待をpとすると、2回目の期待はm/n*p、3回目の期待は(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 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#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
",p/(1-q)); } return 0; }