Розглянемо об'єднану послідовність:
Її довжина дорівнює . З умови задачі випливає, що ця послідовність:
впорядкована в порядку незростання;
складається з чисел від до .
Таким чином, задача зводиться до підрахунку кількості незростаючих послідовностей
Виконаємо заміну змінних:
Тоді всі y_i \ge 0, а їхня сума дорівнює
Отже, задача зводиться до підрахунку способів розкласти число n - 1 на 2m + 1 невід'ємних цілих доданків. Кожному такому розкладенню відповідає рівно одна незростаюча послідовність x_1, x_2, ..., x_{2m}, а значить — рівно одна пара масивів .
За класичною формулою для комбінацій з повтореннями число таких розкладів дорівнює C_{n+2m-1}^{2m} (див. задачу Єолімп ).
Приклад
У першому тесті існує підходящих варіантів:
a = [1, 1], b = [2, 2];
a = [1, 2], b = [2, 2];
a = [2, 2], b = [2, 2];
a = [1, 1], b = [2, 1];
a = [1, 1], b = [1, 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));