「Andrey and Problem」题解
做法超级简单,先从小到大排序,然后从后向前扫,选上更优就选上,不然就 \(break\)
证明。
反证法:假设选择集合不是后缀
假设现在有一个选择集合 \(S\)(存储的是下标),找到这个集合出现的空隙(即 \(i \notin S,i-1\in S\))。
令 $$T = \complement_S{i - 1}$$
令 $$f(P) = \Pi(1 - x_{p_i}), g(P) = \sum \frac{x_{p_i}}{1 - x_{p_i}},a = x_i, b = x_{i - 1}$$
则有:\(a > b\)
容易得到计算答案的式子: $$f (P) * g (P)$$
即证 $$f(T \bigcup {i}) * g(T \bigcup {i}) > f(T \bigcup {i - 1}) * g(T \bigcup {i - 1})$$
即证 $$f(T) * (1 - a) * (g (T) + \frac{a}{1-a}) > f(T) * (1 - b) * (g (T) + \frac{b}{1-b})$$
即证 $$f(T) * g (T) * (1 - a) + \frac{a}{1 - a} * (1 - a) * f (T) > f(T) * g (T) * (1 - b) + \frac{b}{1 - b} * (1 - b) * f (T)$$
即证 $$f(T) * g (T) * (1 - a) + a * f (T) > f(T) * g (T) * (1 - b) + b * f (T)$$
即证 $$g (T) - g (T) * a + a > g (T) - g (T) * b + b$$
即证 $$(1 - g (T)) * a > (1 - g (T)) * b$$
得证。
#include <map>
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <algorithm>
using namespace std;
template <typename T> T Max (T x, T y) { return x > y ? x : y; }
template <typename T> T Min (T x, T y) { return x < y ? x : y; }
template <typename T> T Abs (T x) { return x > 0 ? x : -x; }
template <typename T>
void read (T &x) {
x = 0; T f = 1;
char ch = getchar ();
while (ch < '0' || ch > '9') {
if (ch == '-') f = -1;
ch = getchar ();
}
while (ch >= '0' && ch <= '9') {
x = (x << 3) + (x << 1) + ch - '0';
ch = getchar ();
}
x *= f;
}
template <typename T>
void write (T x) {
if (x < 0) {
x = -x;
putchar ('-');
}
if (x < 10) {
putchar (x + '0');
return;
}
write (x / 10);
putchar (x % 10 + '0');
}
template <typename T>
void print (T x, char ch) {
write (x); putchar (ch);
}
const int Maxn = 100;
const double eps = 1e-10;
int n;
double a[Maxn + 5];
int main () {
// freopen (".in", "r", stdin);
// freopen (".out", "w", stdout);
cin >> n; for (int i = 1; i <= n; i++) cin >> a[i];
sort (a + 1, a + 1 + n);
if (Abs (a[n] - 1) < eps) {
printf ("%.12lf", 1.0);
return 0;
}
double t = 1, tot = 0;
for (int i = n; i >= 1; i--) {
if (t * (1 - a[i]) * (tot + a[i] / (1 - a[i])) < t * tot)
break;
t *= (1 - a[i]);
tot += a[i] / (1 - a[i]);
}
printf ("%.12lf", t * tot);
return 0;
}
浙公网安备 33010602011771号