zoukankan      html  css  js  c++  java
  • FZU

    FZU - 2103 Bin & Jing in wonderland

      题目大意:有n个礼物,每次得到第i个礼物的概率是p[i],一个人一共得到了k个礼物,然后按编号排序后挑选出r个编号最大的礼物。现在给出r个礼物的编号,问能得到这r个礼物的概率。

      首先剩下的k-r个礼物中的编号肯定不能大于r个礼物中最小的编号id,我们就根据id把礼物分成两部分,一部分就是编号大于Id的礼物的,另一部分就是剩下的。对于编号大于id的礼物选取的概率,当前剩余nk1个空位,那么就是挑选num[i]个位置来放它,C[nk1][num[i]*pow(p[i],num[i]),然后概率累乘。而剩下的部分,空位有nk2=k-r+num[id]个,小于id是礼物概率之和是pn,那么我们枚举id礼物有i个,小于id的就有nk2-i个,第一个可以在[1,id)内任意取,第二个也是一样。。这部分概率就是pow(pn,nk2-i),那id礼物有i个这种情况下的概率就是C[nk2][i]*pow(p[id],i)*pow(pn,nk2-i),然后概率累加。最后两部分的概率相乘就是最终答案。

     1 #include<cstdio>
     2 #include<algorithm>
     3 using namespace std;
     4 typedef long long ll;
     5 int num[25];
     6 ll C[55][55];
     7 double p[25];
     8 void init()
     9 {
    10     for(int i=0;i<=52;i++)
    11     {
    12         C[i][0]=1ll;
    13         for(int j=1;j<=i;j++)
    14         {
    15             if(j<=i/2)
    16                 C[i][j]=C[i-1][j-1]+C[i-1][j];
    17             else
    18                 C[i][j]=C[i][i-j];
    19         }
    20     }
    21 } 
    22 double pow(double x,int y)
    23 {
    24     double ans=1.0;
    25     while(y)
    26     {
    27         if(y&1)
    28             ans*=x;
    29         x*=x;
    30         y>>=1;
    31     }
    32     return ans;
    33 }
    34 int main()
    35 {
    36     init();
    37     int t,n,k,r;
    38     scanf("%d",&t);
    39     while(t--)
    40     {
    41         scanf("%d%d%d",&n,&k,&r);
    42         for(int i=1;i<=n;i++)
    43         {
    44             scanf("%lf",&p[i]);
    45             num[i]=0;
    46         }
    47         int id=n+1,x;
    48         for(int i=1;i<=r;i++)
    49         {
    50             scanf("%d",&x);
    51             id=min(id,x);
    52             num[x]++;
    53         }
    54         int nk1=k,nk2=k-r+num[id];
    55         double ans1=1.0,ans2=0.0,pn=0.0;
    56         for(int i=id+1;i<=n;i++)
    57         {
    58             if(num[i])
    59             {
    60                 ans1*=1.0*C[nk1][num[i]]*pow(p[i],num[i]);
    61                 nk1-=num[i];//用了num[i]个位置,减去 
    62             }
    63         }
    64         for(int i=1;i<id;i++)
    65             pn+=p[i];
    66         for(int i=num[id];i<=nk2;i++)
    67             ans2+=1.0*C[nk2][i]*pow(p[id],i)*pow(pn,nk2-i);
    68         printf("%.6f
    ",ans1*ans2);
    69     }
    70     return 0;
    71 }
    看概率过

      

  • 相关阅读:
    Guns 01 项目基本运行
    个人 比较好用的软件
    个人 软件开发 综合技能提升
    开源框架 综合知识
    开源框架 工作流框架
    开源框架 Java 开发框架 1
    开源框架 Java 管理系统
    开源框架 C#
    scp(安全拷贝)和rsync(增量复制)
    完全分布式集群的准备工作
  • 原文地址:https://www.cnblogs.com/LMCC1108/p/10809148.html
Copyright © 2011-2022 走看看