题意:给出n个礼物 , 取k个礼物 , 给出k次礼物中ID前r大的礼物 , 问你这样概率是多少 。
首先剩下的礼物中的ID肯定小于等于前r大的礼物中的最小的那个min_r 。 因此我们枚举在剩下礼物中ID为min_r的个数,设个数为t , 这样我们就可以得到r+t个礼物的概率 ,而且可以保证剩下的k-r-t个礼物中的ID肯定不会和r+t个礼物中的ID相等 ,那么我们就可以把剩下的礼物看成是一个整体(这样就能保证 , 所有礼物的总概率为1)
代码:
首先剩下的礼物中的ID肯定小于等于前r大的礼物中的最小的那个min_r 。 因此我们枚举在剩下礼物中ID为min_r的个数,设个数为t , 这样我们就可以得到r+t个礼物的概率 ,而且可以保证剩下的k-r-t个礼物中的ID肯定不会和r+t个礼物中的ID相等 ,那么我们就可以把剩下的礼物看成是一个整体(这样就能保证 , 所有礼物的总概率为1)
代码:
#include
#include
#include
#include
#include
#include
#define EPS 1e-9
#define LL long long int
using namespace std;
int N,K,R;
int num[30];
double p[30];
double C(int n,int m)
{
doublesum=1.0;
inti,j;
for(i=m;i>=m-n+1; i--)
{
sum*=1.0*i;
}
for(j=1;j<=n; j++)
{
sum/=(1.0*j);
}
returnsum;
}
double POW(double pp,int num)
{
doubleres=1;
int i;
for(i=1;i<=num; i++)
{
res*=pp;
}
returnres;
}
int main()
{
//freopen("input.txt","r",stdin);
int T;
inti,j;
scanf("%d",&T);
while(T--)
{
int MIN=10000;
scanf("%d %d%d",&N,&K,&R);
memset(num,0,sizeof(num));
for(i=1; i<=N; i++)
{
scanf("%lf",&p[i]);
}
for(i=1; i<=R; i++)
{
int temp;
scanf("%d",&temp);
num[temp]++;
MIN=min(MIN,temp);
}
int k=K;
double temp=0;
for(i=1; i
{
temp+=p[i];
}
double ans=0;
int t;
for(t=0; t<=K-R; t++)
{
double p1=1.0;
num[MIN]+=t; // 枚举剩下礼物的ID为base最小那个ID的个数
k=K;
for(i=1; i<=N; i++)
{
if(num[i])
{
p1=p1*C(num[i],k)*POW(p[i],num[i]);
k-=num[i];
}
}
double pp=p1;
int tt=K-R-t;
while(tt>0)
{
pp*=temp; // 剩下没有枚举到的概率
tt--;
}
ans+=pp;
num[MIN]-=t;
}
printf("%.6lf\n",ans);
}
return0;
}