RUВход: восемь задач, шесть тем
Банк дня устроен как экзамен: восемь задач ступени YMLS идут вперемешку, и так они придут 4 сентября — без заголовка «вероятность» над условием. Каждая проще того, что ты решал в свой сильный день по её теме; опасность не в них, а в первых тридцати секундах: неверный первый ход стоит двадцати минут, которых при восьми задачах нет.
Часть 1. Первые тридцать секунд
Правило: сначала вслух тип и первый ход, потом ручка. Пока условие не переведено в одну фразу, счёт не начинается.
| В условии стоит | Тип | Первый ход |
|---|
| «максимум равен», «минимум равен» | Распределение экстремума | Считать «все не больше $t$», взять разность |
| «в среднем», матожидание числа шагов | Матожидание целой величины | Хвостовая формула через $\P(X \ge k)$ |
| «наудачу выбирается точка» | Геометрическая вероятность | Неравенство, область, доля площади |
| «ни один не на своём месте» | Беспорядки | Включения-исключения или перебор |
| «сколько делителей», «сколькими способами» | Счёт | Правило произведения по независимым выборам |
| Уравнение плоскости и точка | Линал | Нормаль читается прямо из коэффициентов |
| «работают одновременно», «за сколько успеют» | Скорости | Сложить скорости, поделить, округлить вверх |
| Интеграл с $e^{-x}$ по лучу $[0,\infty)$ | Табличный интеграл | Гамма-интеграл, ответ $n!$ |
Семь строк из восьми — пункты блока «Мост»; новая только первая, ей посвящена часть 2. Любая из семи вспоминается дольше пары секунд — восстанавливай сейчас.
Регламент, который меняет тактикуНа онлайн-этапе принимается только числовой ответ: обоснование не сдаётся, ход решения не проверяется. Значит способ получения числа выбираешь ты, и машинный ничем не хуже. Правило времени: аналитический ход не найден за 10 минут — переходи к машинному.
Часть 2. Считай хвост, а не значение
Задача. Кубик бросают $n$ раз. Чему равна вероятность того, что максимум равен $t$?
Прямой счёт требует разбора случаев: ровно одна $t$ и остальные меньше, ровно две и остальные меньше, и так далее — сумма из $n$ слагаемых с биномиальными коэффициентами. Ход, убирающий разбор целиком: событие «максимум не больше $t$» означает, что каждый бросок не больше $t$, а такие условия независимы, поэтому вероятность есть степень; «равно» получается вычитанием вложенного события «все не больше $t-1$»:
$$\P(\max \le t) = \left(\frac{t}{6}\right)^{n}, \qquad \P(\max = t) = \frac{t^{n} - (t-1)^{n}}{6^{n}}$$Для минимума всё зеркально: «минимум не меньше $t$» означает, что каждый бросок не меньше $t$, значит $\P(\min \ge t) = \left(\frac{7-t}{6}\right)^{n}$. Работает это по одной причине: «не больше $t$» — условие на каждое испытание по отдельности, и вероятность распадается в произведение, а «равно $t$» — условие на весь набор сразу, и оно не распадается.
Тот же ход для матожидания. Хвостовая формула из блока «Мост» переводит $\E X$ в сумму $\P(X \ge k)$, и работа сводится к вопросу, что значит «$X \ge k$» на языке испытаний. Кубик бросают до первой шестёрки: событие $\{N \ge k\}$ означает, что первые $k-1$ бросков шестёрку не дали, поэтому $\P(N \ge k) = (5/6)^{k-1}$ и $\E N = \frac{1}{1 - 5/6} = 6$ — геометрическая прогрессия вместо ряда с множителем $k$ внутри.
Часть 3. Непрерывный исход: неравенство, область, площадь
Если точка выбирается наудачу в фигуре, исходов бесконечно много и считать нечего: вероятность есть доля площади (блок «Мост»). Вся работа — превратить словесное условие в область. Пример — это финал второго дня, y0202, и он берётся сюда готовым: $X$ и $Y$ независимы и равномерны на $[0,1]$, найти $\P(|X-Y| < 1/3)$. Пара $(X,Y)$ равномерна в единичном квадрате, условие $|x-y| < 1/3$ вырезает полосу вдоль диагонали, а вне полосы остаются два прямоугольных треугольника с катетами $2/3$:
$$\P = 1 - 2\cdot\frac12\left(\frac23\right)^{2} = 1 - \frac49 = \frac59 \approx 0.5556$$Когда в условии стоит расстояние, появляется корень: возводить неравенство в квадрат здесь законно, обе части неотрицательны. После возведения квадраты координат часто сокращаются, и граница оказывается параболой — это не совпадение: «расстояние до точки равно расстоянию до прямой» и есть определение параболы с фокусом и директрисой.
Что здесь теряют«Ближайшая сторона» — это четыре разных условия, а не одно: квадрат режется диагоналями на четыре треугольника, в каждом ближайшая сторона своя, и по симметрии достаточно посчитать один и умножить на 4. И площадь подобласти всегда делится на площадь фигуры — для единичного квадрата делить не на что, про деление и забывают.
Часть 4. Машина считает: точный перебор
Первый вопрос — размер пространства исходов. Ориентир вчерашнего дня: $10^8$ простых операций в секунду, значит перебор до нескольких миллионов исходов мгновенный. Шесть бросков кубика — это $6^6 = 46656$, перестановки шести элементов — $6! = 720$, двоичные строки длины 12 — $2^{12} = 4096$: всё перебирается быстрее, чем вспоминается формула. Граница около $10^7$: подмножества 20 предметов ($2^{20} \approx 10^6$) ещё считаются, а перестановки 12 элементов ($12! \approx 4.8\cdot10^8$) — уже нет.
import itertools
from fractions import Fraction as F
c = sum(1 for t in itertools.product(range(1, 7), repeat=6) if max(t) == 5)
print(c, F(c, 6**6), round(float(F(c, 6**6)), 4)) # 11529 427/1728 0.2471
Ответ выходит точным: Fraction не округляет по дороге. И перебор стоит запускать даже тогда, когда формула найдена: два независимых пути к одному числу — надёжнейшая из проверок.
Часть 5. Машина считает: динамика
Когда пространство не помещается в перебор, тот же счёт делается динамикой. Три вопроса, всегда в этом порядке: состояние — какой минимальный набор данных описывает подзадачу; переход — как значение в состоянии выражается через уже посчитанные; база — с чего всё начинается.
Пример. Сколькими способами набрать сумму 30 упорядоченной последовательностью слагаемых из $\{1,3,5\}$? Состояние: $dp[i]$ — число способов набрать сумму $i$. Переход: смотрим, каким было последнее слагаемое, отсюда $dp[i] = dp[i-1] + dp[i-3] + dp[i-5]$; база $dp[0] = 1$.
n = 30
dp = [0] * (n + 1); dp[0] = 1
for i in range(1, n + 1):
for c in (1, 3, 5):
if i >= c:
dp[i] += dp[i - c]
print(dp[:6], dp[n]) # [1, 1, 1, 2, 3, 5] 390257Проверка руками занимает минуту и обязательна: сумму 4 дают $1{+}1{+}1{+}1$, $1{+}3$ и $3{+}1$ — ровно три последовательности, и в выводе действительно dp[4] = 3.
Порядок циклов меняет саму задачуВнешний цикл по сумме, внутренний по номиналам — считаются упорядоченные последовательности, их 390257. Поменяй циклы местами — получатся неупорядоченные разбиения, и для той же суммы 30 их всего 40. Код отличается двумя строками, ответ — почти в десять тысяч раз, поэтому маленький случай, проверенный руками, обязателен.
Часть 6. Жадность: первый ход, который можно доказать
Иногда перебор не нужен вовсе: локально лучший выбор оказывается глобально верным, и всё дело в слове «оказывается». Классика: дан набор отрезков, выбрать максимальное число попарно непересекающихся.
iv = [(1,4), (3,5), (0,6), (5,7), (3,9), (5,9), (6,10), (8,11), (8,12), (2,14), (12,16)]
iv.sort(key=lambda p: p[1]) # по ПРАВОМУ концу
cnt, end = 0, float('-inf')
for s, e in iv:
if s >= end:
cnt += 1; end = e
print(cnt) # 4Сортировка решает всёПо правому концу — верно: взяв отрезок, заканчивающийся раньше всех, оставляем максимум места остальным. Формально это аргумент обмена: в любом оптимальном решении первый отрезок можно заменить на самый рано заканчивающийся, не ухудшив результат. По левому концу — неверно: на наборе $(0,10)$, $(0,4)$, $(5,9)$ такая жадность возьмёт длинный отрезок и остановится на одном вместо двух. Жадность без аргумента обмена — догадка. Задачи на жадность в банке дня нет намеренно: на онлайн-этапе она почти не встречается, зато про сортировку по правому концу спрашивают на собеседовании. Поэтому здесь сниппет, который надо набрать и запустить, а не задача, которую надо решить.
Часть 7. Машина считает: симуляция
Когда исход непрерывный, перебора не существует вовсе, а интеграл берётся плохо, остаётся Монте-Карло: повторить опыт много раз и взять долю.
import numpy as np
rng = np.random.default_rng(0)
p = rng.random((5_000_000, 2))
print((np.abs(p[:, 0] - p[:, 1]) < 1/3).mean()) # 0.5557418 — четвёртый знак уже врёт
Точный ответ этой задачи посчитан в части 3: $5/9 = 0.5556$ — пять миллионов испытаний четвёртого знака не дали.
Сколько знаков стоит за симуляциейПогрешность доли имеет порядок $1/\sqrt{N}$: миллион испытаний — примерно три верных знака, сто миллионов — четыре, и формат «четыре знака после запятой» симуляция сама не закрывает. Отсюда дисциплина: симуляция — для проверки, аналитика — для точности. Аналитики нет вовсе — гони $10^8$ испытаний и помни, что последний знак ненадёжен.
Часть 8. Символьные вычисления за десять секунд
import sympy as sp, numpy as np
x = sp.Symbol('x')
print(sp.integrate(x**5 * sp.exp(-x), (x, 0, sp.oo))) # 120
print(sp.limit((sp.exp(x**2) - sp.cos(x)) / x**2, x, 0)) # 3/2
n = np.array([1., 2, 2]); p = np.array([1., 2, 3])
print(abs(n @ p - 6) / np.linalg.norm(n)) # 1.6666666666666667
print(np.linalg.det(np.array([[3., 1, 2], [0, 5, 1], [4, 2, 7]]))) # 62.99999999999999Определитель numpy приближённый: $62.99999999999999$ означает ровно $63$, за точным значением иди в sympy.Matrix. А если 4 сентября не окажется самого sympy, символьный ответ заменяется численным: scipy.integrate.quad вместо sp.integrate, scipy.optimize.brentq вместо sp.nsolve, а mpmath.quad берёт даже несобственные интегралы по $[0,\infty)$. Проверь сегодня, что у тебя импортируется: numpy, sympy, scipy, mpmath. Узнать это на экзамене — потерять задачу.
Дисциплина: оценка — счёт — сверка- Оценка руками до счёта: какого порядка ответ, ближе он к нулю или к единице, больше пяти или меньше. Записать до того, как считаешь.
- Счёт — аналитический или машинный, любой.
- Сверка с оценкой, а если это стоит тридцати секунд — и вторым независимым путём. Ответ, противоречащий оценке, — почти всегда ошибка в постановке, а не в машине.
И последнее: на очном экзамене 20 сентября компьютера не будет. Сегодняшний арсенал — оружие для 4 сентября, а не замена умению считать руками.
Что должно остаться в голове
- Сначала тип и первый ход вслух, потом ручка. Неверный первый ход стоит двадцати минут.
- «Максимум или минимум равен $t$» — разность двух хвостов; факторизуется именно хвост.
- Матожидание целой величины — сумма $\P(X \ge k)$; работа в том, чтобы описать это событие словами.
- Непрерывный исход: неравенство, область, доля площади; корень убирается возведением в квадрат, граница часто парабола.
- Меньше нескольких миллионов исходов — точный перебор и
Fraction; больше — динамика. - Динамика: состояние, переход, база. Порядок циклов меняет смысл ответа.
- Жадность верна только там, где проходит аргумент обмена.
- Симуляция даёт три знака за миллион испытаний и четыре — за сто миллионов.
ENOpening: eight problems, six topics
Today’s bank is arranged like the exam: eight YMLS problems appear in mixed order, and that is how they will arrive on September 4—without a “probability” heading above the statement. Each is easier than what you solved on your strongest day in its topic; the danger is the first thirty seconds: a wrong first move costs twenty minutes that you do not have across eight problems.
Part 1. The first thirty seconds
The rule is: say the type and first move aloud, then pick up the pen. Do not start calculating until the statement has been translated into one sentence.
| The statement says | Type | First move |
|---|
| “the maximum equals,” “the minimum equals” | Extreme-value distribution | Count “everything is at most $t$,” then take a difference |
| “on average,” expected number of steps | Expectation of an integer-valued variable | Use the tail formula via $\P(X \ge k)$ |
| “a point is chosen at random” | Geometric probability | Inequality, region, area fraction |
| “nothing is in its original position” | Derangement | Inclusion–exclusion or enumeration |
| “how many divisors,” “in how many ways” | Counting | Product rule for independent choices |
| Plane equation and a point | Linear algebra | Read the normal directly from the coefficients |
| “work simultaneously,” “how long will it take” | Rates | Add the rates, divide, round up |
| Integral with $e^{-x}$ over the ray $[0,\infty)$ | Table integral | Gamma integral; the answer is $n!$ |
Seven of the eight rows are “Bridge” points; only the first is new, and Part 2 is devoted to it. If any of the seven takes more than a couple of seconds to recall, restore it now.
The rule that changes the tacticThe online stage accepts only a numerical answer: no justification is submitted and the solution path is not checked. You choose how to obtain the number, and a machine is just as valid. Time rule: if you have not found an analytical route in 10 minutes, switch to a machine method.
Part 2. Count the tail, not the value
Problem. A die is rolled $n$ times. What is the probability that the maximum equals $t$?
Direct counting requires casework: exactly one $t$ with all the rest smaller, exactly two with all the rest smaller, and so on—a sum of $n$ terms with binomial coefficients. The move that removes all the casework is this: “the maximum is at most $t$” means every roll is at most $t$; the conditions are independent, so the probability is a power. “Equals” is then obtained by subtracting the nested event “everything is at most $t-1$”:
$$\P(\max \le t) = \left(\frac{t}{6}\right)^{n}, \qquad \P(\max = t) = \frac{t^{n} - (t-1)^{n}}{6^{n}}$$For the minimum, mirror the argument: “the minimum is at least $t$” means every roll is at least $t$, so $\P(\min \ge t) = \left(\frac{7-t}{6}\right)^{n}$. This works for one reason: “at most $t$” is a condition on each trial separately, so the probability factors into a product, while “equals $t$” is a condition on the whole collection and does not factor.
The same move for expectation. The “Bridge” tail formula turns $\E X$ into a sum of $\P(X \ge k)$, and the work is to describe “$X \ge k$” in the language of the trials. Roll a die until the first six: the event $\{N \ge k\}$ means the first $k-1$ rolls were not six, so $\P(N \ge k) = (5/6)^{k-1}$ and $\E N = \frac{1}{1 - 5/6} = 6$—a geometric progression instead of a series with a factor k inside.
Part 3. Continuous outcome: inequality, region, area
When a point is chosen at random inside a figure, there are infinitely many outcomes and nothing to count: probability is an area fraction (“Bridge”). The whole job is to turn the verbal condition into a region. Example: this is final y0202 from day 2, brought here ready-made: $X$ and $Y$ are independent and uniform on $[0,1]$; find $\P(|X-Y| < 1/3)$. The pair $(X,Y)$ is uniform in the unit square, and $|x-y| < 1/3$ cuts out a strip along the diagonal. Outside the strip are two right triangles with legs $2/3$:
$$\P = 1 - 2\cdot\frac12\left(\frac23\right)^{2} = 1 - \frac49 = \frac59 \approx 0.5556$$When the statement contains distance, a square root appears: squaring the inequality is legal here because both sides are nonnegative. After squaring, coordinate squares often cancel, and the boundary turns out to be a parabola—not a coincidence: “distance to a point equals distance to a line” is the definition of a parabola with a focus and directrix.
What people lose here“The nearest side” means four different conditions, not one: the square is cut by its diagonals into four triangles, each with its own nearest side, and by symmetry it is enough to calculate one and multiply by 4. Also, the subregion’s area is always divided by the figure’s area—for a unit square there is nothing to divide by, so people forget the division.
Part 4. Let the machine count: exact enumeration
The first question is the size of the outcome space. Yesterday’s reference is $10^8$ simple operations per second, so enumerating a few million outcomes is instant. Six die rolls are $6^6 = 46656$, permutations of six elements are $6! = 720$, and binary strings of length 12 number $2^{12} = 4096$: each can be enumerated faster than you can recall the formula. The boundary is around $10^7$: subsets of 20 items ($2^{20} \approx 10^6$) are still feasible, but permutations of 12 items ($12! \approx 4.8\cdot10^8$) are not.
import itertools
from fractions import Fraction as F
c = sum(1 for t in itertools.product(range(1, 7), repeat=6) if max(t) == 5)
print(c, F(c, 6**6), round(float(F(c, 6**6)), 4)) # 11529 427/1728 0.2471
The answer is exact: Fraction does not round along the way. Run the enumeration even when you have found a formula: two independent paths to the same number are the most reliable check.
Part 5. Let the machine count: dynamic programming
When the outcome space does not fit in enumeration, the same count can be done with dynamic programming. Ask three questions, always in this order: state—what smallest set of data describes the subproblem; transition—how the state value is expressed through values already computed; base—where it begins.
Example. How many ordered sequences of summands from $\{1,3,5\}$ add up to 30? State: $dp[i]$ is the number of ways to make sum $i$. Transition: look at the last summand, giving $dp[i] = dp[i-1] + dp[i-3] + dp[i-5]$; base: $dp[0] = 1$.
n = 30
dp = [0] * (n + 1); dp[0] = 1
for i in range(1, n + 1):
for c in (1, 3, 5):
if i >= c:
dp[i] += dp[i - c]
print(dp[:6], dp[n]) # [1, 1, 1, 2, 3, 5] 390257Check it by hand; it takes a minute and is mandatory: sum 4 comes from $1{+}1{+}1{+}1$, $1{+}3$, and $3{+}1$—exactly three sequences—and the output really has dp[4] = 3.
Loop order changes the problem itselfOuter loop over sums and inner loop over denominations counts ordered sequences, 390257 of them. Swap the loops and you get unordered partitions; for the same sum 30 there are only 40. The code differs by two lines and the answer by almost a factor of ten thousand, so a small hand-checked case is mandatory.
Part 6. Greedy methods: a first move you can prove
Sometimes enumeration is unnecessary: a locally best choice turns out to be globally correct, and everything hinges on the words “turns out.” Classic problem: given intervals, choose the maximum number of pairwise non-overlapping ones.
iv = [(1,4), (3,5), (0,6), (5,7), (3,9), (5,9), (6,10), (8,11), (8,12), (2,14), (12,16)]
iv.sort(key=lambda p: p[1]) # by the RIGHT endpoint
cnt, end = 0, float('-inf')
for s, e in iv:
if s >= end:
cnt += 1; end = e
print(cnt) # 4Sorting decides everythingSorting by right endpoint is correct: choosing the interval that ends earliest leaves the most room for the rest. Formally, this is an exchange argument: in any optimal solution, replace its first interval with the earliest-finishing one without making the result worse. Sorting by left endpoint is wrong: on $(0,10)$, $(0,4)$, $(5,9)$, that greedy choice takes the long interval and stops at one instead of two. Greedy without an exchange argument is just a guess. There is deliberately no greedy problem in today’s bank: it is rare in the online stage, but interviews do ask about sorting by right endpoint. So this is a snippet to type and run, not a problem to solve.
Part 7. Let the machine count: simulation
When the outcome is continuous, enumeration does not exist at all, and the integral is difficult, use Monte Carlo: repeat the experiment many times and take the fraction.
import numpy as np
rng = np.random.default_rng(0)
p = rng.random((5_000_000, 2))
print((np.abs(p[:, 0] - p[:, 1]) < 1/3).mean()) # 0.5557418 — the fourth digit is already wrong
The exact answer for this problem was calculated in Part 3: $5/9 = 0.5556$—five million trials did not deliver a reliable fourth digit.
How many digits simulation buys youThe error of a fraction is on the order of $1/\sqrt{N}$: a million trials give about three correct digits, one hundred million give four, and the “four digits after the decimal point” format cannot be guaranteed by simulation alone. Hence the discipline: simulation is for checking; analysis is for precision. If there is no analytical route at all, run $10^8$ trials and remember that the last digit is unreliable.
Part 8. Symbolic computation in ten seconds
import sympy as sp, numpy as np
x = sp.Symbol('x')
print(sp.integrate(x**5 * sp.exp(-x), (x, 0, sp.oo))) # 120
print(sp.limit((sp.exp(x**2) - sp.cos(x)) / x**2, x, 0)) # 3/2
n = np.array([1., 2, 2]); p = np.array([1., 2, 3])
print(abs(n @ p - 6) / np.linalg.norm(n)) # 1.6666666666666667
print(np.linalg.det(np.array([[3., 1, 2], [0, 5, 1], [4, 2, 7]]))) # 62.99999999999999NumPy’s determinant is approximate: $62.99999999999999$ means exactly $63$; for an exact value, use sympy.Matrix. And if sympy is unavailable on September 4, replace symbolic answers with numeric ones: scipy.integrate.quad instead of sp.integrate, scipy.optimize.brentq instead of sp.nsolve, and mpmath.quad can even handle improper integrals over $[0,\infty)$. Check today that numpy, sympy, scipy, and mpmath import correctly. Discovering that in the exam costs a problem.
Discipline: estimate—calculate—check- Estimate by hand before calculating: what order of magnitude should the answer have; is it closer to zero or one; greater than five or less? Write it down first.
- Calculate—analytically or by machine, either is fine.
- Check against the estimate, and if it takes thirty seconds, against a second independent route.
An answer that contradicts the estimate is almost always a setup error, not a machine error.
Finally, the in-person exam on September 20 will have no computer. Today’s arsenal is a weapon for September 4, not a replacement for the ability to calculate by hand.
What should stay in your head
- Say the type and first move aloud, then pick up the pen. A wrong first move costs twenty minutes.
- “The maximum or minimum equals $t$” is the difference of two tails; it is the tail that factors.
- The expectation of an integer-valued variable is the sum of $\P(X \ge k)$; the work is describing that event in words.
- Continuous outcome: inequality, region, area fraction; remove the root by squaring, and the boundary is often a parabola.
- Fewer than a few million outcomes: exact enumeration with
Fraction; more: dynamic programming. - Dynamic programming: state, transition, base. Loop order changes the meaning of the answer.
- Greedy is correct only where an exchange argument applies.
- Simulation gives three digits for a million trials and four for one hundred million.