1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
#include <iostream>
#include <vector>
#include <algorithm>
#include <iomanip>
#include <cmath>

using namespace std;

struct Question {
    double p;
    double expected;
};

bool compare(const Question &a, const Question &b) {
    return a.expected > b.expected;
}

double calculateProbability(const vector<Question> &questions, int t) {
    const int OFFSET = 1000;  // Offset to handle negative points
    const int MAX_POINTS = 2 * OFFSET;  // Maximum range of points
    vector<double> dp_prev(MAX_POINTS + 1, 0.0);
    dp_prev[OFFSET] = 1.0;  // Start with 0 points (shifted by OFFSET)

    for (const auto &q : questions) {
        vector<double> dp_current(MAX_POINTS + 1, 0.0);
        for (int points = 0; points <= MAX_POINTS; ++points) {
            if (dp_prev[points] > 0) {
                // Case 1: Answer the question correctly
                if (points + 1 <= MAX_POINTS) {
                    dp_current[points + 1] += dp_prev[points] * q.p;
                }
                // Case 2: Answer the question incorrectly
                if (points - 1 >= 0) {
                    dp_current[points - 1] += dp_prev[points] * (1 - q.p);
                }
            }
        }
        dp_prev = dp_current;
    }

    double probability = 0.0;
    for (int points = OFFSET + t; points <= MAX_POINTS; ++points) {
        probability += dp_prev[points];
    }

    return probability;
}

int main() {
    int n, t;
    cin >> n >> t;
    vector<Question> questions(n);
    for (int i = 0; i < n; ++i) {
        cin >> questions[i].p;
        questions[i].expected = 2 * questions[i].p - 1;
    }

    sort(questions.begin(), questions.end(), compare);

    double maxProbability = calculateProbability(questions, t);

    cout << fixed << setprecision(20) << maxProbability << endl;

    return 0;
}