11725. Два массива

 

Даны два числа n и m. Найдите количество таких пар массивов (a, b), что:

·        оба массива имеют длину m;

·        каждый элемент каждого массива – целое число от 1 до n включительно;

·        aibi для любого индекса 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 ≤ x1x2 ≤ … ≤ x2mn

Сделаем замену переменных. Пусть

y1 = x1 – 1, y2 = x2x1, y3 = x3x2, …, y2m = x2mx2m-1, y2m+1 = nx2m

Теперь каждое 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 ≤ a1a2b2b1 ≤ 2.

Сделаем замену переменных:

y1 = a1 – 1, y2 = a2a1, y3 = b2a2, y4 = b1b2, y5 = 2b1

Просуммируем переменные:

y1 + y2 + … + y5 = 1, 0yi ≤ 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));