<|instruction|>
Solve the below problem. The solution should start with an abridged problem statement. Then key observations. Then full solution based on the observations. Then C++ and Python implementations with comments.

338. Casino
Time limit per test: 0.25 second(s)
Memory limit: 65536 kilobytes
input: standard
output: standard



Consider the following dice game. Player rolls a regular dice (with the numbers 1 through 6 on its sides) several times and calculates total amount of points each time. Player can finish his turn after any roll. Thus, player should make at least one roll. If the sum exceeds 21, player loses. When player finishes, croupier rolls a dice using the same scheme. Player wins, if he or she has more points than croupier. More formally, if player has Sp points and croupier has Sc points, than player wins if and only if (Sp ≤ 21 and (Sc > 21 or Sc < Sp)). The optimal croupier's strategy allows casino to win in more than 2/3 cases. But Andrew found the possibility to raise his chances to win! He will play together with Big Man. Big Man will bet X euros each game, while Andrew will bet 1 euro each game. In case of the win player gets his bet doubled. In case of the loss player gets nothing.

The scheme of the game is like following.

1. Big Man rolls dice several times and stops following the "best" strategy—the strategy that would be optimal if he played with croupier and without Andrew (he is really Big and doesn't care about little Andrew).

2. Than Andrew rolls dice several times. Andrew knows the amount of points Big Man has. Andrew is very smart boy and he realizes that croupier's strategy maximizes profit of the casino. So, Andrew uses optimal strategy using all those facts.

3. Finally, croupier rolls dice several times. As mentioned above, croupier uses optimal strategy.

We call strategy  if it maximizes expected profit. If after the next roll any player or croupier have the same expected profit with the current value, he or she will prefer to roll the dice.

As Andrew calculated if X is big enough, he has almost 50 percents chance to win!

Input
The input contains one integer X (0 ≤ X ≤ 1000).

Output
Print one number—probability of Andrew's win. Your answer must be accurate up to 10-5.

Example(s)
sample input
sample output
0
0.331176

sample input
sample output
1
0.345634

%
sample input
sample output
%5
%
%0.454301
%

<|response|>
## 1. Abridged problem statement

There is a dice game similar to blackjack with limit `21`.

A player rolls a fair six-sided die at least once and may stop after any roll. If their sum exceeds `21`, they lose. After the player stops, the croupier plays by the same rules. The player wins iff:

```text
player_sum <= 21 and (croupier_sum > 21 or croupier_sum < player_sum)
```

Two players play before the croupier:

1. Big Man bets `X` euros and plays the optimal strategy he would use if Andrew did not exist.
2. Andrew bets `1` euro, sees Big Man’s final score, and plays optimally.
3. The croupier then plays optimally for the casino, maximizing total expected casino profit from both bets.

If a player/croupier is indifferent between stopping and rolling, they roll.

Given `X`, output Andrew’s probability of winning.

---

## 2. Key observations needed to solve the problem

### Observation 1: Work with expected value instead of probability

For Andrew’s unit bet:

- if Andrew wins, his net profit is `+1`;
- if Andrew loses, his net profit is `-1`.

If Andrew wins with probability `p`, then his expected value is:

```text
EV = p * 1 + (1 - p) * (-1) = 2p - 1
```

So after computing Andrew’s expected value:

```text
p = (EV + 1) / 2
```

---

### Observation 2: Only sums `0..27` matter

The maximum non-bust score is `21`.

If a player has at most `21` and rolls once more, the largest possible new score is:

```text
21 + 6 = 27
```

Therefore all DP arrays only need indices `0..27`.

Scores `22..27` are bust states.

---

### Observation 3: Dynamic programming works backwards

Rolling always increases the current sum, so when computing the value for score `s`, all future states `s + 1 ... s + 6` are larger.

Therefore we can compute DP values in decreasing order of score.

---

### Observation 4: Big Man ignores Andrew

Big Man uses the optimal strategy for the one-player game against the croupier.

His bet size `X` does not affect his strategy because multiplying all profits by `X` does not change which action is better.

So first we compute Big Man’s strategy independently.

---

### Observation 5: The croupier optimizes casino profit, not Andrew’s loss directly

After both Big Man and Andrew have stopped, the croupier maximizes:

```text
casino profit against Big Man + casino profit against Andrew
```

More precisely:

```text
X * profit_from_Big_Man + profit_from_Andrew
```

Andrew’s expected value must follow the croupier’s casino-optimal decision.

So while computing croupier DP, we need to store two values:

```text
g[Sc] = casino's total expected profit
a[Sc] = Andrew's expected profit under the same croupier action
```

The croupier chooses actions by maximizing `g`, while `a` simply follows that choice.

---

## 3. Full solution approach based on the observations

Let `N = 28`, representing sums `0..27`.

Define a helper:

```text
roll_avg(v, s) = average of v[s + 1], ..., v[s + 6]
```

This is the expected value after one die roll from sum `s`.

---

### Step 1: Compute Big Man’s stopping value

Suppose Big Man stops with score `Sb`.

We compute the croupier’s optimal response in the one-player game.

Let:

```text
f[Sc] = Big Man's expected profit when croupier currently has score Sc
```

If `Sc > 21`, croupier busted, so Big Man wins:

```text
f[Sc] = +1
```

For `Sc <= 21`, croupier can stop or roll.

If croupier stops:

```text
Big Man wins iff Sc < Sb
```

So:

```text
stop_value = +1 if Sc < Sb
stop_value = -1 otherwise
```

If croupier rolls:

```text
roll_value = roll_avg(f, Sc)
```

The croupier minimizes Big Man’s expected profit. If equal, croupier rolls:

```text
f[Sc] = min(stop_value, roll_value)
```

with tie going to `roll_value`.

Because croupier must roll at least once, Big Man’s expected value after stopping at `Sb` is:

```text
U_b[Sb] = roll_avg(f, 0)
```

---

### Step 2: Compute Big Man’s strategy

Let:

```text
V_bm[Sb] = Big Man's optimal expected profit at current score Sb
```

If `Sb > 21`, Big Man busted:

```text
V_bm[Sb] = -1
```

Otherwise Big Man can stop or roll:

```text
stop_value = U_b[Sb]
roll_value = roll_avg(V_bm, Sb)
```

Big Man maximizes expected profit. If equal, he rolls.

We also store his action for every score.

Then we simulate Big Man’s final score distribution.

Initially, he must roll once:

```text
reach[1..6] = 1/6
```

Then for every reachable score:

- if Big Man rolls, distribute probability to `score + 1 ... score + 6`;
- if he stops, add probability to final distribution;
- bust states `22..27` are final.

This gives:

```text
dist_b[Sb] = probability Big Man finishes with score Sb
```

---

### Step 3: Compute Andrew’s stopping value for fixed Big Man score

Now fix Big Man’s final score `Sb`.

Suppose Andrew stops with score `Sa`.

We compute the croupier’s optimal strategy against both players.

Let:

```text
g[Sc] = casino's total expected profit
a[Sc] = Andrew's expected profit under the croupier's casino-optimal strategy
```

If `Sc > 21`, croupier busted.

Then:

- Big Man wins if `Sb <= 21`, otherwise Big Man already busted.
- Andrew wins if `Sa <= 21`, otherwise Andrew already busted.

For `Sc <= 21`, the croupier compares stopping and rolling.

If croupier stops, casino profit from Big Man is:

```text
+X if Big Man busted or Sc >= Sb
-X otherwise
```

Casino profit from Andrew is:

```text
+1 if Andrew busted or Sc >= Sa
-1 otherwise
```

Andrew’s own EV is:

```text
-1 if Andrew loses
+1 if Andrew wins
```

If croupier rolls:

```text
roll_casino = roll_avg(g, Sc)
roll_andrew = roll_avg(a, Sc)
```

The croupier chooses the action with larger casino EV. If equal, croupier rolls.

After computing this DP, croupier must roll at least once, so Andrew’s EV if he stops at `Sa` is:

```text
stop_andrew[Sa] = roll_avg(a, 0)
```

---

### Step 4: Compute Andrew’s optimal strategy for fixed Big Man score

Let:

```text
V_a[Sa] = Andrew's optimal expected profit at current score Sa
```

If `Sa > 21`, Andrew busted:

```text
V_a[Sa] = -1
```

Otherwise Andrew can stop or roll:

```text
stop_value = stop_andrew[Sa]
roll_value = roll_avg(V_a, Sa)
```

Andrew maximizes his own expected profit. If equal, he rolls.

Since Andrew must roll at least once:

```text
andrew_ev(Sb) = roll_avg(V_a, 0)
```

---

### Step 5: Average over Big Man’s final score distribution

Andrew sees Big Man’s final score, so his strategy depends on `Sb`.

Therefore:

```text
total_ev = sum(dist_b[Sb] * andrew_ev(Sb))
```

Finally:

```text
answer = (total_ev + 1) / 2
```

The state space is tiny, so the solution is easily fast enough.

---

## 4. C++ implementation with detailed comments

```cpp
#include <bits/stdc++.h>
using namespace std;

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    double X;
    cin >> X;

    // We only need scores 0..27.
    // 22..27 are bust states.
    const int N = 28;

    // Expected value after rolling one die from score s.
    auto roll_avg = [&](const vector<double>& v, int s) {
        double sum = 0.0;
        for (int d = 1; d <= 6; d++) {
            sum += v[s + d];
        }
        return sum / 6.0;
    };

    // ------------------------------------------------------------
    // Step 1: Big Man's stopping values in the one-player game.
    // ------------------------------------------------------------

    // U_b[Sb] = Big Man's EV if he stops with score Sb.
    // Bust states are initialized to -1.
    vector<double> U_b(N, -1.0);

    for (int Sb = 1; Sb <= 21; Sb++) {
        // f[Sc] = Big Man's EV when the croupier currently has score Sc.
        vector<double> f(N, 0.0);

        // If croupier busts, Big Man wins.
        for (int Sc = 22; Sc < N; Sc++) {
            f[Sc] = 1.0;
        }

        // Compute croupier strategy backwards.
        for (int Sc = 21; Sc >= 1; Sc--) {
            // If croupier stops, Big Man wins only if Sc < Sb.
            double stop_value = (Sc < Sb) ? 1.0 : -1.0;

            // If croupier rolls.
            double roll_value = roll_avg(f, Sc);

            // Croupier minimizes Big Man's EV.
            // If equal, croupier rolls.
            if (roll_value <= stop_value) {
                f[Sc] = roll_value;
            } else {
                f[Sc] = stop_value;
            }
        }

        // Croupier must roll at least once.
        U_b[Sb] = roll_avg(f, 0);
    }

    // ------------------------------------------------------------
    // Step 2: Big Man's optimal strategy and final distribution.
    // ------------------------------------------------------------

    // V_bm[Sb] = Big Man's optimal EV at current score Sb.
    vector<double> V_bm(N, -1.0);

    // action_bm[Sb] = 1 means roll, 0 means stop.
    vector<int> action_bm(N, 0);

    for (int Sb = N - 1; Sb >= 1; Sb--) {
        if (Sb > 21) {
            // Bust state: already initialized to -1.
            continue;
        }

        double stop_value = U_b[Sb];
        double roll_value = roll_avg(V_bm, Sb);

        // Big Man maximizes EV.
        // If equal, he rolls.
        if (roll_value >= stop_value) {
            V_bm[Sb] = roll_value;
            action_bm[Sb] = 1;
        } else {
            V_bm[Sb] = stop_value;
            action_bm[Sb] = 0;
        }
    }

    // reach[Sb] = probability that Big Man reaches score Sb.
    vector<double> reach(N, 0.0);

    // Big Man must roll once initially.
    for (int d = 1; d <= 6; d++) {
        reach[d] = 1.0 / 6.0;
    }

    // dist_b[Sb] = probability Big Man finishes with final score Sb.
    vector<double> dist_b(N, 0.0);

    for (int Sb = 1; Sb <= 21; Sb++) {
        if (action_bm[Sb] == 1) {
            // Big Man rolls, distribute probability.
            for (int d = 1; d <= 6; d++) {
                reach[Sb + d] += reach[Sb] / 6.0;
            }
        } else {
            // Big Man stops here.
            dist_b[Sb] = reach[Sb];
        }
    }

    // Bust states are final.
    for (int Sb = 22; Sb < N; Sb++) {
        dist_b[Sb] = reach[Sb];
    }

    // ------------------------------------------------------------
    // Function: Andrew's optimal EV given Big Man's final score Sb.
    // ------------------------------------------------------------

    auto andrew_ev_given = [&](int Sb) {
        // stop_andrew[Sa] = Andrew's EV if he stops at score Sa.
        vector<double> stop_andrew(N, -1.0);

        // Compute Andrew's stopping value for every possible Sa.
        for (int Sa = 1; Sa <= 21; Sa++) {
            // g[Sc] = casino's total EV from croupier score Sc.
            // a[Sc] = Andrew's EV under the croupier action maximizing g.
            vector<double> g(N, 0.0), a(N, 0.0);

            // Boundary: croupier has busted.
            for (int Sc = 22; Sc < N; Sc++) {
                // Casino profit against Big Man.
                double casino_big;
                if (Sb > 21) {
                    // Big Man already busted, casino wins his bet.
                    casino_big = X;
                } else {
                    // Croupier busts, Big Man wins.
                    casino_big = -X;
                }

                // Andrew is not busted here because Sa is 1..21,
                // so croupier bust means Andrew wins.
                double casino_andrew = -1.0;
                double andrew_ev = 1.0;

                g[Sc] = casino_big + casino_andrew;
                a[Sc] = andrew_ev;
            }

            // Compute croupier strategy backwards.
            for (int Sc = 21; Sc >= 1; Sc--) {
                // Casino profit from Big Man if croupier stops.
                double stop_big;
                if (Sb > 21) {
                    stop_big = X;
                } else {
                    stop_big = (Sc >= Sb) ? X : -X;
                }

                // Casino profit from Andrew if croupier stops.
                double stop_andrew_casino = (Sc >= Sa) ? 1.0 : -1.0;

                // Andrew's own EV if croupier stops.
                double stop_andrew_ev = (Sc >= Sa) ? -1.0 : 1.0;

                double stop_casino = stop_big + stop_andrew_casino;

                // Values if croupier rolls.
                double roll_casino = roll_avg(g, Sc);
                double roll_andrew_ev = roll_avg(a, Sc);

                // Croupier maximizes casino EV.
                // If equal, croupier rolls.
                if (roll_casino >= stop_casino) {
                    g[Sc] = roll_casino;
                    a[Sc] = roll_andrew_ev;
                } else {
                    g[Sc] = stop_casino;
                    a[Sc] = stop_andrew_ev;
                }
            }

            // Croupier must roll at least once.
            stop_andrew[Sa] = roll_avg(a, 0);
        }

        // Now compute Andrew's optimal rolling/stopping strategy.
        vector<double> V_a(N, -1.0);

        for (int Sa = N - 1; Sa >= 1; Sa--) {
            if (Sa > 21) {
                // Bust state.
                continue;
            }

            double stop_value = stop_andrew[Sa];
            double roll_value = roll_avg(V_a, Sa);

            // Andrew maximizes his own EV.
            // If equal, he rolls.
            V_a[Sa] = max(stop_value, roll_value);
        }

        // Andrew must roll at least once.
        return roll_avg(V_a, 0);
    };

    // ------------------------------------------------------------
    // Step 5: Average Andrew's EV over Big Man's distribution.
    // ------------------------------------------------------------

    double total_ev = 0.0;

    for (int Sb = 1; Sb < N; Sb++) {
        if (dist_b[Sb] > 0.0) {
            total_ev += dist_b[Sb] * andrew_ev_given(Sb);
        }
    }

    // Convert EV to probability.
    double probability = (total_ev + 1.0) / 2.0;

    cout << fixed << setprecision(6) << probability << '\n';

    return 0;
}
```

---

## 5. Python implementation with detailed comments

```python
import sys


def main():
    X = float(sys.stdin.readline())

    # Scores 0..27 are enough.
    # Scores greater than 21 are bust states.
    N = 28

    def roll_avg(values, s):
        """
        Expected value after rolling one fair six-sided die
        from current score s.
        """
        return sum(values[s + d] for d in range(1, 7)) / 6.0

    # ------------------------------------------------------------
    # Step 1: Big Man's stopping values in the one-player game.
    # ------------------------------------------------------------

    # U_b[Sb] = Big Man's EV if he stops at score Sb.
    U_b = [-1.0] * N

    for Sb in range(1, 22):
        # f[Sc] = Big Man's EV when croupier currently has score Sc.
        f = [0.0] * N

        # If croupier busts, Big Man wins.
        for Sc in range(22, N):
            f[Sc] = 1.0

        # Croupier decisions, computed backwards.
        for Sc in range(21, 0, -1):
            # If croupier stops, Big Man wins only if Sc < Sb.
            stop_value = 1.0 if Sc < Sb else -1.0

            # If croupier rolls.
            roll_value = roll_avg(f, Sc)

            # Croupier minimizes Big Man's EV.
            # If equal, croupier rolls.
            f[Sc] = roll_value if roll_value <= stop_value else stop_value

        # Croupier must roll at least once.
        U_b[Sb] = roll_avg(f, 0)

    # ------------------------------------------------------------
    # Step 2: Big Man's optimal strategy.
    # ------------------------------------------------------------

    # V_bm[Sb] = Big Man's optimal EV at current score Sb.
    V_bm = [-1.0] * N

    # action_bm[Sb] = 1 means roll, 0 means stop.
    action_bm = [0] * N

    for Sb in range(N - 1, 0, -1):
        if Sb > 21:
            # Bust state.
            continue

        stop_value = U_b[Sb]
        roll_value = roll_avg(V_bm, Sb)

        # Big Man maximizes EV.
        # If equal, he rolls.
        if roll_value >= stop_value:
            V_bm[Sb] = roll_value
            action_bm[Sb] = 1
        else:
            V_bm[Sb] = stop_value
            action_bm[Sb] = 0

    # ------------------------------------------------------------
    # Step 3: Big Man's final score distribution.
    # ------------------------------------------------------------

    # reach[Sb] = probability Big Man reaches score Sb.
    reach = [0.0] * N

    # Big Man must roll once initially.
    for d in range(1, 7):
        reach[d] = 1.0 / 6.0

    # dist_b[Sb] = probability Big Man finishes with score Sb.
    dist_b = [0.0] * N

    for Sb in range(1, 22):
        if action_bm[Sb] == 1:
            # Big Man rolls.
            for d in range(1, 7):
                reach[Sb + d] += reach[Sb] / 6.0
        else:
            # Big Man stops.
            dist_b[Sb] = reach[Sb]

    # Bust states are final states.
    for Sb in range(22, N):
        dist_b[Sb] = reach[Sb]

    # ------------------------------------------------------------
    # Step 4: Andrew's optimal EV for a fixed Big Man score.
    # ------------------------------------------------------------

    def andrew_ev_given(Sb):
        """
        Compute Andrew's optimal expected profit,
        assuming Big Man's final score is Sb.
        """

        # stop_andrew[Sa] = Andrew's EV if he stops at score Sa.
        stop_andrew = [-1.0] * N

        for Sa in range(1, 22):
            # g[Sc] = casino's total EV.
            # a[Sc] = Andrew's EV under the same croupier decision.
            g = [0.0] * N
            a = [0.0] * N

            # Boundary: croupier has busted.
            for Sc in range(22, N):
                if Sb > 21:
                    # Big Man already busted, casino wins his bet.
                    casino_big = X
                else:
                    # Croupier busts, Big Man wins.
                    casino_big = -X

                # Since Sa is 1..21 here, croupier bust means Andrew wins.
                casino_andrew = -1.0
                andrew_ev = 1.0

                g[Sc] = casino_big + casino_andrew
                a[Sc] = andrew_ev

            # Croupier chooses stop/roll to maximize casino EV.
            for Sc in range(21, 0, -1):
                # Casino profit from Big Man if croupier stops.
                if Sb > 21:
                    stop_big = X
                else:
                    stop_big = X if Sc >= Sb else -X

                # Casino profit from Andrew if croupier stops.
                stop_andrew_casino = 1.0 if Sc >= Sa else -1.0

                # Andrew's own EV if croupier stops.
                stop_andrew_ev = -1.0 if Sc >= Sa else 1.0

                stop_casino = stop_big + stop_andrew_casino

                # Values if croupier rolls.
                roll_casino = roll_avg(g, Sc)
                roll_andrew_ev = roll_avg(a, Sc)

                # Croupier maximizes casino EV.
                # If equal, croupier rolls.
                if roll_casino >= stop_casino:
                    g[Sc] = roll_casino
                    a[Sc] = roll_andrew_ev
                else:
                    g[Sc] = stop_casino
                    a[Sc] = stop_andrew_ev

            # Croupier must roll at least once.
            stop_andrew[Sa] = roll_avg(a, 0)

        # Andrew's own rolling/stopping DP.
        V_a = [-1.0] * N

        for Sa in range(N - 1, 0, -1):
            if Sa > 21:
                # Bust state.
                continue

            stop_value = stop_andrew[Sa]
            roll_value = roll_avg(V_a, Sa)

            # Andrew maximizes EV.
            # If equal, he rolls.
            V_a[Sa] = roll_value if roll_value >= stop_value else stop_value

        # Andrew must roll at least once.
        return roll_avg(V_a, 0)

    # ------------------------------------------------------------
    # Step 5: Average over Big Man's final score distribution.
    # ------------------------------------------------------------

    total_ev = 0.0

    for Sb in range(1, N):
        if dist_b[Sb] > 0.0:
            total_ev += dist_b[Sb] * andrew_ev_given(Sb)

    # Convert expected value to probability.
    probability = (total_ev + 1.0) / 2.0

    print(f"{probability:.6f}")


if __name__ == "__main__":
    main()
```