题目描述:
每个人有
pi
p
i
的概率提供一道题给Andrey,求Andrey得到恰好一道题的最大概率
分析:
显然,我们如果想要概率最大,就要从大到小的选择
我们先把概率从大到小排序
贪心的选取就好了
简单说一下怎么计算答案:
简单观察一下
假设现在我们已经选中了
p1,p2
p
1
,
p
2
ans=p1∗(1−p2)+p2∗(1−p1)
a
n
s
=
p
1
∗
(
1
−
p
2
)
+
p
2
∗
(
1
−
p
1
)
现在我们要插入
p3
p
3
ans′=p1∗(1−p2)∗(1−p3)+p2∗(1−p1)∗(1−p3)+p3∗(1−p1)∗(1−p2)
a
n
s
′
=
p
1
∗
(
1
−
p
2
)
∗
(
1
−
p
3
)
+
p
2
∗
(
1
−
p
1
)
∗
(
1
−
p
3
)
+
p
3
∗
(
1
−
p
1
)
∗
(
1
−
p
2
)
ans′=(1−p3)∗(p1∗(1−p2)+p2∗(1−p1))+p3∗(1−p1)∗(1−p2)
a
n
s
′
=
(
1
−
p
3
)
∗
(
p
1
∗
(
1
−
p
2
)
+
p
2
∗
(
1
−
p
1
)
)
+
p
3
∗
(
1
−
p
1
)
∗
(
1
−
p
2
)
设
t
t
为已选中的元素的的乘积
ans
a
n
s
为当前答案
ans′=ans∗(1−pi)+pi∗t,t′=t∗(1−pi)
a
n
s
′
=
a
n
s
∗
(
1
−
p
i
)
+
p
i
∗
t
,
t
′
=
t
∗
(
1
−
p
i
)
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int N=110;
int n;
double p[N];
int cmp(const double &a,const double &b) {
return a>b;
}
int main()
{
scanf("%d",&n);
for (int i=1;i<=n;i++) scanf("%lf",&p[i]);
sort(p+1,p+1+n,cmp);
double ans=p[1],t=1.0-p[1];
for (int i=2;i<=n;i++) {
double o=ans*(1.0-p[i])+t*p[i];
if (o>ans) ans=o,t*=(1-p[i]);
else break;
}
printf("%0.9lf\n",ans);
return 0;
}