【概率论】hdu5985 Lucky Coins

kill(i,j)表示第i种硬币在第j轮或者之前就死光的概率,它等于(1-pi^j)^num(i)

rev(i,j)表示第i种硬币在j轮后仍然存活的概率,它等于1-kill(i,j)

然后对每种硬币i模拟100轮左右,每一轮答案要加上 在j轮后i仍然存活的概率*(在第j轮时其他恰好死光的概率《   这个值等于(∏(kill(j,k))-∏(kill(j,k-1)))(i!=j)   》)

注意,一定要特判n==1时输出1.000000,因为我们模拟时并没有考虑第0轮。

#include<cstdio>
using namespace std;
double Quick_Pow(double x,int k){
	if(!k){
		return 1;
	}
	double res=Quick_Pow(x,k>>1);
	res*=res;
	if(k&1){
		res*=x;
	}
	return res;
}
int Zu,n,a[11];
double anss[11],p[11],rev[11][111],kill[11][111],kills[111];
int main(){
//	freopen("d.in","r",stdin);
	scanf("%d",&Zu);
	for(int zu=1;zu<=Zu;++zu){
		scanf("%d",&n);
		for(int i=1;i<=n;++i){
			scanf("%d%lf",&a[i],&p[i]);
		}
		if(n==1){
			printf("%.6f
",1.0);
			continue;
		}
		for(int i=1;i<=n;++i){
			double pi_j=1;
			for(int j=1;j<=100;++j){
				pi_j*=p[i];
				kill[i][j]=Quick_Pow(1.0-pi_j,a[i]);
				rev[i][j]=1.0-kill[i][j];
			}
		}
		for(int i=1;i<=n;++i){
			for(int k=1;k<=100;++k){
				kills[k]=1;
				for(int j=1;j<=n;++j){
					if(i!=j){
						kills[k]*=kill[j][k];
					}
				}
			}
			anss[i]=rev[i][1]*kills[1];
			for(int k=2;k<=99;++k){
				anss[i]+=rev[i][k]*kills[k];
				anss[i]-=rev[i][k]*kills[k-1];
			}
			anss[i]-=rev[i][100]*kills[99];
		}
		for(int i=1;i<n;++i){
			printf("%.6lf ",anss[i]);
		}
		printf("%.6lf
",anss[n]);
	}
	return 0;
}
原文地址:https://www.cnblogs.com/autsky-jadek/p/6682743.html