多项分布介绍:
http://blog.youkuaiyun.com/shuimu12345678/article/details/30773929
每个事件p必须相互独立。所以在本题中需要枚举最小的那个事件的次数。然后比最小的还小的概率当成一个独立的事件,然后正常算就好了。
代码
#include<stdio.h>
#include<map>
#include<math.h>
using namespace std;
const int maxn = 25;
int N,k,r;
double p[maxn];
map<int,int>MAP;
double A(int x)
{
double ret=1;
for(int i=1;i<=x;i++) ret*=i;
return ret;
}
void solve()
{
MAP.clear();
scanf("%d %d %d",&N,&k,&r);
for(int i=1;i<=N;i++) scanf("%lf",p+i);
for(int i=1;i<=r;i++)
{
int tp;
scanf("%d",&tp);
MAP[tp]++;
}
double ppp = 0;
for(int i=1;i<MAP.begin()->first;i++) ppp+=p[i];
double P = 0;
for(int i=0;i<=k-r;i++)
{
double pp = A(k);
for(map<int,int>::iterator it = MAP.begin();it!=MAP.end();++it)
if(it==MAP.begin()) pp*=pow(p[it->first],it->second+i)/A(it->second+i);
else pp*=pow(p[it->first],it->second)/A(it->second);
pp*=pow(ppp,k-r-i)/A(k-r-i);
P+=pp;
}
printf("%.6lf\n",P);
}
int main()
{
int T;
scanf("%d",&T);
while(T--) solve();
return 0;
}