题意:就是有n种礼物,然后可以选取K个,但是你想得到ID比较大的r个,现在给出了你选取的ID号,让你求得到此序列概率。
题解:
就是把你已经选取的r个,令L=最小的ID,,此时要把1到L-1看成一个整体来计算,然后枚举L可以有的个数,L到N就按照排列组合计算就行。
(此时要把1到L-1看成一个整体来计算)这里你思考一下就会懂
我举个例子假如 l=3, 1的概率为0.3,2的概率为0.4,此时k-r-t=2,
Bin has a dream that he and Jing are both in a wonderland full of beautiful gifts. Bin wants to choose some gifts for Jing to get in her good graces.
There are N different gifts in the wonderland, with ID from 1 to N, and all kinds of these gifts have infinite duplicates. Each time, Bin shouts loudly, “I love Jing”, and then the wonderland random drop a gift in front of Bin. The dropping probability for gift i (1≤i≤N) is P(i). Of cause, P(1)+P(2)+…+P(N)=1. Bin finds that the gifts with the higher ID are better. Bin shouts k times and selects r best gifts finally.
That is, firstly Bin gets k gifts, then sorts all these gifts according to their ID, and picks up the largest r gifts at last. Now, if given the final list of the r largest gifts, can you help Bin find out the probability of the list?
Input
The first line of the input contains an integer T (T≤2,000), indicating number of test cases.
For each test cast, the first line contains 3 integers N, k and r (1≤N≤20, 1≤k≤52, 1≤r≤min(k,25)) as the description above. In the second line, there are N positive float numbers indicates the probability of each gift. There are at most 3 digits after the decimal point. The third line has r integers ranging from 1 to N indicates the finally list of the r best gifts’ ID.
Output
For each case, output a float number with 6 digits after the decimal points, which indicates the probability of the final list.
Sample Input
4 2 3 3 0.3 0.7 1 1 1 2 3 3 0.3 0.7 1 1 2 2 3 3 0.3 0.7 1 2 2 2 3 3 0.3 0.7 2 2 2
Sample Output
0.027000 0.189000 0.441000 0.343000
#include<stdio.h>
#include<algorithm>
#include<string.h>
using namespace std;
double possi[100];
int num[100];
int qw[100];
int n,k,r;
int l;
double multi(int a,int b)
{
double d=1;
for(int i=a;i>b;i--)
{
d*=i;
d/=(a-i+1);
}
return d;
}
double solve(int t)
{
qw[l]+=t;
double ans=1,p=0;
int w=k;
for(int i=1;i<l;i++)
p+=possi[i];
for(int i=l;i<=n;i++)
{
ans*=multi(w,qw[i]);
for(int j=0;j<qw[i];j++)
{
ans*=possi[i];
}
w-=qw[i];
}
for(int i=1;i<=k-r-t;i++)
ans*=p;
qw[l]-=t;
return ans;
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d%d%d",&n,&k,&r);
memset(qw,0,sizeof(qw));
for(int i=1;i<=n;i++)
{
scanf("%lf",&possi[i]);
}
l=n;
for(int i=1;i<=r;i++)
{
scanf("%d",&num[i]);
qw[num[i]]++;
l=min(l,num[i]);
}
double ans=0;
if(l==1)
{
ans=solve(k-r);
}
else
{
for(int i=0;i<=k-r;i++)
{
ans+=solve(i);
}
}
printf("%.6f\n",ans);
}
return 0;
}