Два масиви#11725

Два масиви (Розбір)

Розглянемо об'єднану послідовність:

a_1, a_2, ..., a_m, b_m, b_{m - 1}, ..., b_1

Її довжина дорівнює . З умови задачі випливає, що ця послідовність:

Таким чином, задача зводиться до підрахунку кількості незростаючих послідовностей

1 \le x_1 \le x_2 \le ... \le x_{2m} \le n

Виконаємо заміну змінних:

y_1 = x_1 - 1, \\ y_2 = x_2 - x_1, \\ y_3 = x_3 - x_2, \\ ..., \\ y_{2m} = x_{2m} - x_{2m-1}, \\ y_{2m+1} = n - x_{2m}

Тоді всі y_i \ge 0, а їхня сума дорівнює

y_1 + y_2 + ... + y_{2m} + y_{2m+1} = n - 1

Отже, задача зводиться до підрахунку способів розкласти число n - 1 на 2m + 1 невід'ємних цілих доданків. Кожному такому розкладенню відповідає рівно одна незростаюча послідовність x_1, x_2, ..., x_{2m}, а значить — рівно одна пара масивів .

За класичною формулою для комбінацій з повтореннями число таких розкладів дорівнює C_{n+2m-1}^{2m} (див. задачу Єолімп ).

Приклад

У першому тесті існує підходящих варіантів:

Відповідна об'єднана послідовність задовольняє нерівностям

1 \le a_1 \le a_2 \le b_2 \le b_1 \le 2

Зробимо заміну змінних:

y_1 = a_1 - 1, \\ y_2 = a_2 - a_1, \\ y_3 = b_2 - a_2, \\ y_4 = b_1 - b_2, \\ y_5 = 2 - b_1

Просумуємо змінні:

y_1 + y_2 + ... + y_5 = 1, 0 \le y_i \le 1

Це рівняння має рішень. В кожному з них рівно одна змінна y_i дорівнює , а всі інші дорівнюють . Розглянемо відповідність цих рішень до початкових послідовностей:

Реалізація алгоритму

Оголосимо константу і масив , для якого dp[n][k] = C_n^k.

#define MOD 1000000007
long long dp[3001][30];

Функція Cnk обчислює значення біноміального коефіцієнта C_n^k.

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)) % MOD;
}

Основна частина програми. Читаємо вхідні дані.

scanf("%d %d", &n, &m);

Ініціалізуємо масив .

memset(dp, -1, sizeof(dp));

Обчислюємо і виводимо відповідь C_{n+2m-1}^{2m}.

printf("%d\n", Cnk(n + 2 * m - 1, 2 * m));