Марафон - 2022
∙ 𝑎1 = 𝑘, число 𝑘 задано;
∙ любые два соседних элемента различны: 𝑎𝑖 ̸= 𝑎𝑖+1 ;
∙ если 𝑎𝑖 < 𝑎𝑖+1 , то 𝑎𝑖+1 > 𝑎𝑖+2 ;
∙ если 𝑎𝑖 > 𝑎𝑖+1 , то 𝑎𝑖+1 < 𝑎𝑖+2 ;
Примеры
тест ответ
6 2 4
3 3 1
Пояснения к примерам
В первом примере подходят следующие массивы: [2, 1, 2, 1], [2, 1, 3], [2, 3, 1], [2, 4]. Во втором примере един-
ственный подходящий массив [3].
Страница 12 из 34
Подготовка к областной олимпиаде
Марафон - 2022
Для небольших значений 𝑠 можно применить рекурсивный перебор вариантов. При использовании акку-
ратного перебора с отсечениями можно решать задачу при 𝑠 ∼ 30. Если для 𝑠 порядка 30 перебор не успевает
найти ответ за отведенное ограничение по времени, можно применить метод предподсчёта: заранее на своём
компьютере найти ответы для всех тестов с 1 6 𝑘 6 𝑠 6 30 и отправить на проверку программу, которая
выводит найденный заранее ответ.
Решим задачу с помощью динамического программирования. Обозначим как 𝑢𝑝[𝑠][𝑘] количество массивов,
которые удовлетворяют описанным ограничениям, с суммой равной 𝑠, первым элементом равным 𝑘, а второй
элемент строго больше первого. Аналогично введём величину 𝑑𝑜𝑤𝑛[𝑠][𝑘], для количества таких массивов, где
второй элемент строго меньше первого.
Заметим, что 𝑢𝑝[𝑠][𝑠] = 𝑑𝑜𝑤𝑛[𝑠][𝑠] = 1. Для 𝑘 < 𝑠 значения можно вычислить по формулам:
𝑠−𝑘
∑︁
𝑢𝑝[𝑠][𝑘] = 𝑑𝑜𝑤𝑛[𝑠 − 𝑘][𝑖]
𝑖=𝑘+1
𝑘−1
∑︁
𝑑𝑜𝑤𝑛[𝑠][𝑘] = 𝑢𝑝[𝑠 − 𝑘][𝑖]
𝑖=1
Величина, которую требуется найти по условию задачи, равна 𝑢𝑝[𝑠][𝑘] + 𝑑𝑜𝑤𝑛[𝑠][𝑘], не забудем также
отдельный случай 𝑠 = 𝑘, когда ответ равен 1. Время работы такого алгоритма 𝑂(𝑠3 ).
Заметим, что формула для 𝑢𝑝[𝑠][𝑘] отличается от 𝑢𝑝[𝑠][𝑘 + 1] одним слагаемым: 𝑑𝑜𝑤𝑛[𝑠 − 𝑘][𝑘 + 1], поэтому
𝑢𝑝[𝑠][𝑘] = 𝑢𝑝[𝑠][𝑘 + 1] + 𝑑𝑜𝑤𝑛[𝑠 − 𝑘][𝑘 + 1].
Аналогично, 𝑑𝑜𝑤𝑛[𝑠][𝑘] = 𝑑𝑜𝑤𝑛[𝑠][𝑘 − 1] + 𝑢𝑝[𝑠][𝑘 − 1]. Теперь значения вычисляются за 𝑂(1) и время
подсчёта всех значений есть 𝑂(𝑠2 ). Следует обратить внимание, что значения 𝑢𝑝[𝑠][𝑘] следует вычислять по
убыванию 𝑘, а значения 𝑑𝑜𝑤𝑛[𝑠][𝑘] по возрастанию 𝑘.
𝑘
∑︁
𝑠𝑢𝑚𝑈 𝑝[𝑠][𝑘] = 𝑢𝑝[𝑠][𝑖],
𝑖=1
𝑘
∑︁
𝑠𝑢𝑚𝐷𝑜𝑤𝑛[𝑠][𝑘] = 𝑑𝑜𝑤𝑛[𝑠][𝑖].
𝑖=1
Тогда
𝑢𝑝[𝑠][𝑘] = 𝑠𝑢𝑚𝐷𝑜𝑤𝑛[𝑠 − 𝑘][𝑠 − 𝑘] − 𝑠𝑢𝑚𝐷𝑜𝑤𝑛[𝑠 − 𝑘][𝑘],
𝑑𝑜𝑤𝑛[𝑠][𝑘] = 𝑠𝑢𝑚𝑈 𝑝[𝑠][𝑘 − 1].
Отметим, что во всех случаях следует аккуратно следить за тем, чтобы индексы значений, к которым
происходит обращение в формулах, не выходили за пределы массивов и за порядком вычислений.
Страница 13 из 34