[关闭]
@y20070316 2017-04-19T13:48:06.000000Z 字数 1388 阅读 886

XSY 1899 - Lucky Coins

题目 估算 概率论


题意

  我们定义某种硬币为 幸运硬币 : 我们有若干个硬币, 同时将所有的硬币抛起来,然后把反面朝上的硬币移去,留下正面朝上的硬币。接着,再把剩下的硬币同时抛起来,再把反面朝上的硬币移去,直到最终剩下一个种类的硬币或者没有硬币剩下。如果最终剩下一个种类的硬币,那么我们就认为那种硬币为幸运硬币。
  现在给定硬币的种类数、每种硬币的个数、每种硬币抛起来后正面朝上的概率,你需要计算每种硬币成为幸运硬币的概率。

  
  
  
  

分析

  记 表示一枚 抛一次朝上概率为 的硬币, 在前 轮中出现反面朝上的概率, 那么


  对于当前 成为幸运硬币的概率, 我们可以方便地计算答案:

  发现当 比较大时, , 所以我们只用将 枚举到 , 我取了 .

实现

  1. #include <cstdio>
  2. #include <cstring>
  3. #include <cstdlib>
  4. #include <cctype>
  5. #include <cmath>
  6. #define F(i,a,b) for (int i=(a);i<=(b);i++)
  7. #define P(i,a,b) for (int i=(a);i>=(b);i--)
  8. #define D double
  9. const int K=15;
  10. int T;
  11. int k,a[K]; D b[K];
  12. int rd(void) {
  13. int x=0,f=1; char c; for (c=getchar();!isdigit(c);c=getchar()) if (c=='-') f=-1;
  14. for (;isdigit(c);c=getchar()) x=x*10+c-'0'; return x*f;
  15. }
  16. D fail(int turn,D p,int cnt) { return pow( 1-pow(p,(D)turn) ,(D)cnt); }
  17. int main(void) {
  18. #ifndef ONLINE_JUDGE
  19. freopen("C.in","r",stdin);
  20. freopen("C.out","w",stdout);
  21. #endif
  22. T=rd();
  23. F(t,1,T) {
  24. k=rd();
  25. F(i,1,k) {
  26. a[i]=rd();
  27. scanf("%lf",b+i);
  28. }
  29. if (k==1) { printf("1.000000000\n"); continue; }
  30. F(lucky,1,k) {
  31. D ans=0;
  32. F(i,1,50) {
  33. D tmp=1-fail(i,b[lucky],a[lucky]),sum1=1,sum2=1;
  34. F(j,1,k) if (j!=lucky) {
  35. sum1 *= fail(i-1,b[j],a[j]); //全部在 i-1 前炸
  36. sum2 *= fail( i,b[j],a[j]); //全部在 i 前炸
  37. // sum2 - sum1 : 存在至少一个在 i 炸, 且最晚在 i 炸
  38. }
  39. tmp *= (sum2-sum1); ans+=tmp;
  40. }
  41. printf("%0.9lf ",ans);
  42. }
  43. printf("\n");
  44. }
  45. return 0;
  46. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注