Problem:
MathJax.Hub.Config({ tex2jax: { inlineMath: [["$","$"], ["\\(","\\)"]], skipTags: ["script","noscript","style","textarea","code"], processEscapes: true }});

Janken Master

You are supposed to play the rock-paper-scissors game. There are $N$ players including you.

This game consists of multiple rounds. While the rounds go, the number of remaining players decreases. In each round, each remaining player will select an arbitrary shape independently. People who show rocks win if all of the other people show scissors. In this same manner, papers win rocks, scissors win papers. There is no draw situation due to the special rule of this game: if a round is tied based on the normal rock-paper-scissors game rule, the player who has the highest programming contest rating (this is nothing to do with the round!) will be the only winner of the round. Thus, some players win and the other players lose on each round. The losers drop out of the game and the winners proceed to a new round. They repeat it until only one player becomes the winner.

Each player is numbered from $1$ to $N$. Your number is $1$. You know which shape the other $N-1$ players tend to
show, that is to say, you know the probabilities each player shows rock, paper and scissors. The $i$-th player shows rock with $r_i\%$ probability, paper with $p_i\%$ probability, and scissors with $s_i\%$ probability. The rating of programming contest of the player numbered $i$ is $a_i$. There are no two players whose ratings are the same. Your task is to calculate your probability to win the game when you take an optimal strategy based on each player's tendency and rating.

Input

The input consists of a single test case formatted as follows.

$N$
$a_1$
$a_2$ $r_2$ $p_2$ $s_2$
...
$a_N$ $r_N$ $p_N$ $s_N$

The first line consists of a single integer $N$ ($2 \leq N \leq 14$). The second line consists of a single integer
$a_i$ ($1 \leq a_i \leq N$). The ($i+1$)-th line consists of four integers $a_i, r_i, p_i$ and $s_i$ ($1 \leq a_i \leq N, 0 \leq r_i, p_i, s_i \leq 100,$ $r_i + p_i + s_i = 100$) for $i=2, ..., N$. It is guaranteed that $a_1, ..., a_N$ are pairwise distinct.

Output

Print the probability to win the game in one line. Your answer will be accepted if its absolute or relative error does not exceed $10^{-6}$.

Sample Input 1

2
2
1 40 40 20

Output for Sample Input 1

0.8

Since you have the higher rating than the other player, you will win the game if you win or draw in the first round.

Sample Input 2

2
1
2 50 50 0

Output for Sample Input 2

0.5

You must win in the first round.

Sample Input 3

3
2
1 50 0 50
3 0 0 100

Output for Sample Input 3

1

In the first round, your best strategy is to show a rock. You will win the game with $50\%$ in this round. With the other $50\%$, you and the second player proceed to the second round and you must show a rock to win the game.

Sample Input 4

3
2
3 40 40 20
1 30 10 60

Output for Sample Input 4

0.27

Sample Input 5

4
4
1 34 33 33
2 33 34 33
3 33 33 34

Output for Sample Input 5

0.6591870816

Solution in C++14 (judge verdict: Accepted)

#include <bits/stdc++.h>
using namespace std;
#define int long long
#define double long double
#define REP(i, n) for (int i = 0; i < (n); i++)

signed main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    int n;
    cin >> n;
    n--;
    int A;
    cin >> A;
    vector<int> a(n);
    vector<vector<double>> b(3, vector<double>(n));
    REP(i, n) cin >> a[i] >> b[0][i] >> b[1][i] >> b[2][i];
    REP(i, n) b[0][i] /= 100, b[1][i] /= 100, b[2][i] /= 100;

    vector<double> dp(1 << n, -1);
    dp[0] = 1;
    function<double(int)> dfs = [&](int S) {
        if (dp[S] != -1) return dp[S];
        double ret = 0;
        bool ok = true;
        REP(i, n) {
            if ((S >> i & 1) && a[i] > A) ok = false;
        }
        REP(c, 3) {
            double acc = 0.0;
            double draw = 1.0;
            for (int T = S;; T = (T - 1) & S) {
                if (T == S) continue;
                double win = 1.0, lose = 1.0;
                REP(i, n) {
                    if ((S >> i & 1) == 0) continue;
                    win *= ((T >> i & 1) ? b[c][i] : b[(c + 2) % 3][i]);
                    lose *= ((T >> i & 1) ? b[(c) % 3][i] : b[(c + 1) % 3][i]);
                }
                acc += dfs(T) * win;
                draw -= win + lose;
                // acc += exp(dfs(T) + win);
                // draw -= exp(win) + exp(lose);
                if (T == 0) break;
            }
            if (ok) acc += draw;
            ret = max(ret, acc);
        }
        return dp[S] = ret;
    };
    int all = (1 << n) - 1;
    dfs(all);
    // REP(i, 1 << n) cout << i << " " << dp[i] << endl;
    cout << setprecision(20) << dp[all] << endl;
}