博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Codeforces 442B. Andrey and Problem
阅读量:5267 次
发布时间:2019-06-14

本文共 4085 字,大约阅读时间需要 13 分钟。

time limit per test

2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

Andrey needs one more problem to conduct a programming contest. He has n friends who are always willing to help. He can ask some of them to come up with a contest problem. Andrey knows one value for each of his fiends — the probability that this friend will come up with a problem if Andrey asks him.

Help Andrey choose people to ask. As he needs only one problem, Andrey is going to be really upset if no one comes up with a problem or if he gets more than one problem from his friends. You need to choose such a set of people that maximizes the chances of Andrey not getting upset.

Input

The first line contains a single integer n (1 ≤ n ≤ 100) — the number of Andrey's friends. The second line contains n real numbers pi (0.0 ≤ pi ≤ 1.0) — the probability that the i-th friend can come up with a problem. The probabilities are given with at most 6 digits after decimal point.

Output

Print a single real number — the probability that Andrey won't get upset at the optimal choice of friends. The answer will be considered valid if it differs from the correct one by at most 10 - 9.

Examples

Input

4

0.1 0.2 0.3 0.8

Output

0.800000000000

Input

2

0.1 0.2

Output

0.260000000000

Note

In the first sample the best strategy for Andrey is to ask only one of his friends, the most reliable one.

In the second sample the best strategy for Andrey is to ask all of his friends to come up with a problem. Then the probability that he will get exactly one problem is 0.1·0.8 + 0.9·0.2 = 0.26.

题目大意

\(n\)个人,你可以挑出一部分人来向他们要一道题,第\(i\)个人给你题的概率为\(p_i\),你只需要一道题,多了或少了你都不高兴。问在所有的选人方案里,有且仅有一道题的最大概率是多少?

题解

官方题解很明白不是很清楚你们为什么看不懂

先考虑选出的集合$A = { p_1, p_2, p_3, \ldots , p_n } $

概率\(Ans\)

\[Ans = \sum_{i=1}^{n} p_i \prod _{j=1}^{n}[i\neq j] \times (1-p_j)\]
\[=\sum_{i=1}^{n}\frac{p_i}{1-p_i} \prod _{j=1}^{n}(1-p_j)\]
\[=(\prod_{j=1}^{n}(1-p_j))\times(\sum_{i=1}^{n}\frac{p_i}{1-p_i})\]

考虑向集合内添加一个新的元素\(p_x\),对答案的贡献为:

\[\Delta = (\prod_{j=1}^{n}(1-p_j))\times(1-p_x) \times ((\sum_{i=1}^{n}\frac{p_i}{1-p_i}) + \frac{p_x}{1-p_x})) - (\prod_{j=1}^{n}(1-p_j))\times(\sum_{i=1}^{n}\frac{p_i}{1-p_i})\]
看上去非常乱

\(P = \prod_{j=1}^{n}(1-p_j),S=\sum_{i=1}^{n}\frac{p_i}{1-p_i}\)

上述式子改写成

\[Ans = P \times S\]
\[\Delta = P \times (1 - p_x) \times (S + \frac{p_x}{1-p_x}) - P \times S\]
\[=P \times p_x \times (1 - S)\]
发现:

引理1:唯有当\(S < 1\)时,\(x\)才会加入集合

那么对于所有满足\(S < 1\)的元素,我们加哪个更好呢?

考虑两个元素\(i,j,i\neq j\),他们的贡献差为:

\[\Delta ^{'}= \Delta_i - \Delta_j\]
\[=P\times p_i(1 - S) - P \times p_j \times (1-S)\]
\[=P\times (1-S)\times(p_i - p_j)\]
由此得到:

引理2:当元素\(i\)\(j\)更优时,当且仅当\(\Delta ^{'}> 0\),即\(p_i > p_j\)

算法不难得出:按照\(p_i\)排序,不断往里加,一直加到\((1-S) \leq 0\)为止,即为答案

接下来通过上述结论来证明算法正确的充分性,即算法的是正确答案。

考虑反证法,假设最有答案集合为\(A\),存在元素\(i,j\),满足\(i \in A,j \notin B,p_i < p_j\),那我们把\(i\)从集合\(A\)中去掉,此时一定满足\((1-S) > 0\)(不然最优答案为啥要把\(i\)加进去呢)。根据引理1我们可以把\(j\)加进去,根引理2,加入\(j\)比加入\(i\)更优,与\(A\)为最优矛盾。所以\(j\)应该加入答案。

归纳一下算法就是对的了(唔)

此外还要加个特判

因为\(p_i = 1\)的时候S就挂了。。

所以如果出现\(1\),答案就是1,直接输出

其实我相当于把官方题解翻译了一遍,加了点自己的东西觉得更好理解

上述证明写法非常不严谨,大家自行脑补严谨的写法
只是做了点微小的工作,谢谢大家

#include 
#include
#include
#include
#include
#include
#include
inline int max(int a, int b){return a > b ? a : b;}inline int min(int a, int b){return a < b ? a : b;}inline void swap(int &x, int &y){int tmp = x;x = y;y = tmp;}inline void read(int &x){ x = 0;char ch = getchar(), c = ch; while(ch < '0' || ch > '9') c = ch, ch = getchar(); while(ch <= '9' && ch >= '0') x = x * 10 + ch - '0', ch = getchar(); if(c == '-') x = -x;}const int INF = 0x3f3f3f3f;double a[10000 + 10], S, P;int n;bool cmp(double a, double b){ return a > b;}int main(){ read(n); for(int i = 1;i <= n;++ i) scanf("%lf", &a[i]); std::sort(a + 1, a + 1 + n, cmp); if(a[1] == 1) { printf("1"); return 0; } P = 1, S = 0; for(int i = 1;i <= n;++ i) { if(S < 1) { P *= 1 - a[i]; S += a[i] / (1 - a[i]); } } printf("%.10lf", P * S); return 0;}

转载于:https://www.cnblogs.com/huibixiaoxing/p/8608332.html

你可能感兴趣的文章
我的Hook学习笔记
查看>>
js中的try/catch
查看>>
寄Android开发Gradle你需要知道的知识
查看>>
简述spring中常有的几种advice?
查看>>
整理推荐的CSS属性书写顺序
查看>>
ServerSocket和Socket通信
查看>>
css & input type & search icon
查看>>
源代码的下载和编译读后感
查看>>
Kafka学习笔记
查看>>
Octotree Chrome安装与使用方法
查看>>
Windows 环境下基于 Redis 的 Celery 任务调度模块的实现
查看>>
趣谈Java变量的可见性问题
查看>>
C# 强制关闭当前程序进程(完全Kill掉不留痕迹)
查看>>
ssm框架之将数据库的数据导入导出为excel文件
查看>>
语音识别中的MFCC的提取原理和MATLAB实现
查看>>
验证组件FluentValidation的使用示例
查看>>
0320-学习进度条
查看>>
解决windows系统的oracle数据库不能启动ora-00119和ora-00130的问题
查看>>
ip相关问题解答
查看>>
MetaWeblog API Test
查看>>