Нехай f(n, a) — максимально можливе значення очікуваного виграшу, якщо гравцю належить відповісти на питань, а початкова сума дорівнює .
Якщо n = 0, гравець залишається з початковою сумою, тобто f(0, a) = a.
Ймовірність правильної відповіді дорівнює , де t \le p \le 1. Якщо гравець відповідає правильно на перше питання, йому залишається n - 1 питань, а призова сума подвоюється і стає рівною . З ймовірністю 1 - p дається неправильна відповідь, і вся сума пропадає. Отже, очікуваний виграш після першого питання дорівнює
Якщо це значення перевищує поточну суму , то вигідно продовжити гру; інакше — слід зупинитися. Таким чином, очікуваний виграш після рішення про продовження дорівнює
Оскільки ймовірність рівномірно розподілена на відрізку , то
Якщо t = 1, то ймовірність правильної відповіді дорівнює одиниці, і тоді гравець повинен відповідати на всі питань, отримуючи підсумковий виграш 2^n.
Приклад
Розглянемо третій тест, у якому n = 2, t = 0.6. Початковий капітал a = 1.
Обчислимо значення f(1, 2) через f(0, 4):
Обчислимо значення f(2, 1) через f(1, 2):
Реалізація алгоритму
Функція integral обчислює значення інтеграла
для заданих дійсних чисел і . При t = 1 ймовірність вгадування дорівнює одиниці, тому значення інтеграла I(a, k) покладається рівним max(a, k).
Нижче показана область, площа якої дорівнює значенню інтеграла \int_{t}^{1} max(a, kp)\,dp:
Знайдемо точку перетину прямих y = a і y = kp:
Покладемо temp = a / k. Значення інтеграла \int_{t}^{1} max(a, kp)\,dp розглянемо як суму \int_{t}^{temp} a\,dp + \int_{temp}^{1} kp\,dp. Залежно від положення точки відносно точок та обчислюємо значення інтеграла I(a, k).
Якщо t \le temp \le 1, то \int_{t}^{temp} a\,dp + \int_{temp}^{1} kp\,dp =
Якщо temp \le t, то \int_{t}^{temp} a\,dp + \int_{temp}^{1} kp\,dp = \int_{t}^{1} kp\,dp = k \cdot (1 - t \cdot t) / 2.
Якщо temp > 1, то \int_{t}^{temp} a\,dp + \int_{temp}^{1} kp\,dp = \int_{t}^{1} a\,dp = a \cdot (1 - t).
double integral(double a, double k)
{
double s = 0, temp = a / k;
if (t == 1) return max(a,k);
if (temp > 1) return a * (1 - t);
if (temp >= t) s = a * (temp - t);
else temp = t;
s += k * (1 – temp * temp) / 2;
return s / (1 - t);
}Функція f рекурсивно обчислює значення f(n, a) = \begin{cases} I(a, f(n - 1, 2a)), n > 0 \\ a, n = 0 \end{cases}.
double f(int n, int a)
{
if (!n) return a;
double k = f(n - 1,2 * a);
return integral(a,k);
}Основний цикл програми. Читаємо вхідні дані та виводимо значення f(n, 1).
while(scanf("%d %lf",&n,&t),n + t)
printf("%.3lf\n",f(n,1));