@y20070316
2017-04-19T13:48:06.000000Z
字数 1388
阅读 886
题目 估算 概率论
我们定义某种硬币为 幸运硬币 : 我们有若干个硬币, 同时将所有的硬币抛起来,然后把反面朝上的硬币移去,留下正面朝上的硬币。接着,再把剩下的硬币同时抛起来,再把反面朝上的硬币移去,直到最终剩下一个种类的硬币或者没有硬币剩下。如果最终剩下一个种类的硬币,那么我们就认为那种硬币为幸运硬币。
现在给定硬币的种类数、每种硬币的个数、每种硬币抛起来后正面朝上的概率,你需要计算每种硬币成为幸运硬币的概率。
记 表示一枚 抛一次朝上概率为 的硬币, 在前 轮中出现反面朝上的概率, 那么
#include <cstdio>#include <cstring>#include <cstdlib>#include <cctype>#include <cmath>#define F(i,a,b) for (int i=(a);i<=(b);i++)#define P(i,a,b) for (int i=(a);i>=(b);i--)#define D doubleconst int K=15;int T;int k,a[K]; D b[K];int rd(void) {int x=0,f=1; char c; for (c=getchar();!isdigit(c);c=getchar()) if (c=='-') f=-1;for (;isdigit(c);c=getchar()) x=x*10+c-'0'; return x*f;}D fail(int turn,D p,int cnt) { return pow( 1-pow(p,(D)turn) ,(D)cnt); }int main(void) {#ifndef ONLINE_JUDGEfreopen("C.in","r",stdin);freopen("C.out","w",stdout);#endifT=rd();F(t,1,T) {k=rd();F(i,1,k) {a[i]=rd();scanf("%lf",b+i);}if (k==1) { printf("1.000000000\n"); continue; }F(lucky,1,k) {D ans=0;F(i,1,50) {D tmp=1-fail(i,b[lucky],a[lucky]),sum1=1,sum2=1;F(j,1,k) if (j!=lucky) {sum1 *= fail(i-1,b[j],a[j]); //全部在 i-1 前炸sum2 *= fail( i,b[j],a[j]); //全部在 i 前炸// sum2 - sum1 : 存在至少一个在 i 炸, 且最晚在 i 炸}tmp *= (sum2-sum1); ans+=tmp;}printf("%0.9lf ",ans);}printf("\n");}return 0;}
