Вибрати різних цілих чисел із можна C_n^x способами.
Розглянемо, скільки існує підмножин із чисел, мінімальним елементом у яких є число . Для цього в підмножину обов'язково включається число , а також обираються ще x - 1 чисел, кожне з яких строго більше . Чисел, більших від , всього n - i, і обрати з них x - 1 число можна C_{n-i}^{x-1} способами.
Зазначимо також, що повинно виконуватися нерівність i + x - 1 \le n, оскільки інакше неможливо обрати x - 1 чисел, більших від . Звідси слідує обмеження i \le n - x + 1.
Щоб обчислити очікуване значення величини 2^S, необхідно знайти середньозважене значення цієї величини по всіх можливих підмножинах:
Якщо i > n - x + 1, то кількість відповідних підмножин вважається рівним нулю.
Приклад
У першому тесті можливий єдиний варіант вибору: \{1, 2, 3, 4\}. Мінімальним елементом є число , тому шукане значення дорівнює 2^1 = 2.
У другому тесті існує три рівноймовірних варіанти: , і . Відповідні значення рівні , і . Тоді середнє значення величини 2^S дорівнює
Обчислимо вказану відповідь за формулою:
Реалізація алгоритму
Функція Cnk обчислює значення біноміального коефіцієнта C_n^k. Значення біноміальних коефіцієнтів будемо зберігати в осередках масиву .
long long dp[51][51];
long long Cnk(int n, int k)
{
if (n == k) return 1;
if (k == 0) return 1;
if (dp[n][k] != -1) return dp[n][k];
return dp[n][k] = Cnk(n - 1, k - 1) + Cnk(n - 1, k);
}Основна частина програми.
scanf("%d %d", &n, &x);
memset(dp, -1, sizeof(dp));Вичислюємо відповідь: \frac{\sum_{i = 1}^{n - x + 1} 2^i \cdot C_{n - i}^{x - 1}}{C^x_n}.
a = 0;
for (i = 1; i <= n - x + 1; i++)
a = a + Cnk(n - i, x - 1) * (1LL << i);
res = 1.0 * a / Cnk(n, x);Виводимо відповідь.
printf("%lf\n", res);