11725. Два
массива
Даны два числа n и m.
Найдите количество таких пар массивов (a, b), что:
·
оба массива имеют длину m;
·
каждый элемент каждого массива – целое число от 1 до n включительно;
·
ai ≤ bi для любого индекса i от 1 до m;
·
массив a отсортирован в порядке неубывания;
·
массив b отсортирован в порядке невозрастания.
Так как ответ может быть слишком
большим, вычислите его по модулю 109 + 7.
Вход. Два натуральных числа n и m (1
≤ n ≤ 1000, 1 ≤ m ≤ 10).
Выход. Выведите одно число – количество
массивов a и b, удовлетворяющих описанным выше условиям. Ответ
выведите по модулю 109 + 7.
Пример входа 1 |
Пример выхода 1 |
2 2 |
5 |
|
|
Пример входа 2 |
Пример выхода 2 |
723 9 |
157557417 |
комбинаторика
Рассмотрим следующую последовательность: a1, a2, …,
am, bm, bm-1,
…, b1. Ее длина равна 2m, она отсортирована в порядке неубывания,
каждый ее элемент находится на отрезке от 1 до n. Вычислим количество таких
последовательностей.
Данную
последовательность можно представить в виде:
1 ≤ x1
≤ x2 ≤ … ≤ x2m
≤ n
Сделаем замену
переменных. Пусть
y1 = x1 –
1, y2 = x2 – x1, y3
= x3 – x2, …, y2m
= x2m – x2m-1, y2m+1
= n – x2m
Теперь каждое yi ≥ 0, а сумма этих
переменных равна n – 1:
y1 + y2 + … + y2m + y2m+1 = n – 1
Теперь задача
состоит в том, чтобы разбить целое число n – 1 на 2m + 1 слагаемых,
которые могут принимать целые неотрицательные значения. Каждое такое разбиение
соответствует одной неубывающей последовательности x1, x2, …, x2m.
Количество таких
разбиений равно (смотри задачу Еолимп 11551).
Пример
В первом тесте
существуют 5 подходящих вариантов:
·
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]
Рассмотрим последовательность: 1 ≤ a1
≤ a2 ≤ b2 ≤ b1
≤ 2.
Сделаем замену
переменных:
y1 = a1 –
1, y2 = a2 – a1, y3
= b2 – a2, y4 = b1 – b2, y5 = 2 – b1
Просуммируем
переменные:
y1 + y2 + … + y5 = 1, 0 ≤ yi
≤ 1
Это уравнение имеет 5 решений. В каждом решении одно из
значений yi принимает значение 1, а остальные 0. Рассмотрим соответствия
решений уравнения исходным последовательностям:
Реализация алгоритма
Объявим константу и массив dp, для которого dp[n][k] = .
#define MOD 1000000007
long long dp[3001][30];
Функция Cnk вычисляет значение биномиального коэффициента .
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);
Инициализируем массив dp.
memset(dp, -1, sizeof(dp));
Вычисляем и выводим ответ .
printf("%d\n", Cnk(n + 2 * m - 1, 2 *
m));