Дано множество
из n целых чисел. Вы можете выбрать из этого множества k различных элементов, чтобы сформировать
группу. Две группы считаются разными, если существует хотя бы один элемент,
который присутствует в одной группе, но отсутствует в другой. Например, если
множество состоит из 4 элементов a, b, c, d,
и требуется выбрать два элемента, то ab, bc, cd,
bd, ad и ac являются
всеми корректными и различными группами.
Система
группирования называется полной, если для заданного k число различных групп максимально. В
этом примере множество {ab, bc,
cd, bd, ad, ac} образует полную систему группирования.
Для некоторой
полной системы группирования её оценка (fitness) вычисляется следующим образом:
·
каждая группа вносит вклад, равный произведению всех чисел
в этой группе;
·
все вклады групп суммируются;
·
итоговая оценка определяется как суммарный вклад ,
где — ограничивающий параметр.
В приведённом
выше примере, для k = 2, оценка равна
F2 =
(ab + bc + cd + bd + ad
+ ac) mod m
Если k = 1, то оценка равна
F1 =
(a + b + c + d) mod m
Ваша задача – определить
полную систему группирования, которая дает максимально возможную оценку.
Вход. Каждый тест начинается с двух положительных целых чисел n (2 ≤ n
≤ 1000) и m (1 ≤ m < 231). Следующая строка
содержит n натуральных чисел, каждое
из которых не больше 1000. Последний тест содержит n = m = 0 и не
обрабатывается.
Выход. Для каждого теста выведите
в отдельной строке максимально возможную оценку для системы группирования.
|
Пример
входа |
Пример
выхода |
|
4 10 1 2 3 4 4 100 1 2 3 4 4 6 1 2 3 4 0 0 |
5 50 5 |
динамическое программирование
Пусть а1,
a2, …, an – заданные n чисел. Обозначим через Fik (i ³ k) сумму всех
возможных произведений по k чисел, выбранных среди первых i чисел a1, …, ai.
Построим следующую таблицу значений Fik:

Для четырех чисел получаем:
·
F4,1 = a1
+ a2 + a3 + a4;
·
F4,2 = a1a2
+ a1a3 + a1a4 + a2a3 + a2a4 + a3a4;
·
F4,3 = a1a2a3 + a1a2a4 + a1a3a4 + a2a3a4;
·
F4,4 = a1a2a3a4;
Выполняются следующие рекуррентные соотношения:
Fi1 = F(i-1)1 + ai,
Fii = F(i-1) (i-1) * ai,
1 £ i £ n
Fik = F(i-1)k
+ F(i-1) (k-1) * ai,
1 £ i £ n, 1 < k < i
Например,
·
F3,2 = F2,2 + F2,1 * a3 = a1a2
+ (a1 + a2) * a3 = a1a2 + a1a3
+ a2a3;
·
F4,3 = F3,3 + F3,2 * a4 = a1a2a3 + (a1a2 + a1a3 + a2a3) * a4 =
a1a2a3 + a1a2a4 + a1a3a4 + a2a3a4
Значения каждой
следующей строки вычисляются на основе значений предыдущей, поэтому для хранения достаточно
одного линейного массива d размером до 1000. Пересчёт значений i - ой строки следует выполнять с конца:
сначала вычисляется Fii, затем Fi(i-1) и так далее до Fi1.
Все вычисления необходимо проводить по модулю m.
Пример
Рассмотрим
первый тест. Построим две таблицы: в первой вычисления выполняются без модуля, а во
второй – по модулю m = 10.

Например,
·
F4,2 = F3,2 + F3,1 * 4 =
11 + 6 * 4 = 35;
·
F4,3 = F3,3 + F3,2 * 4 =
6 + 11 * 4 = 50;
Ответом является
максимальное значение в четвёртой строке второй таблицы.
Объявим линейный
массив d, в котором будут пересчитываться значения Fik.
long long d[1000];
Вводим
количество чисел n и значение m. Для каждого входного теста предварительно обнуляем
массив d. Первое число a1
заносим в d[0].
while
(scanf("%lld
%lld",&n,&m), n + m > 0)
{
memset(d,0,sizeof(d));
scanf("%lld",&d[0]);
Далее вводим значение x = ai+1
(1 £ i < n) и пересчитываем значения Fik
для k = i, i – 1, …, 1 по приведённым выше
рекуррентным формулам. Все вычисления выполняются по модулю m.
for (i = 1; i
< n; i++)
{
scanf("%lld",&x);
d[i] = (d[i-1] * x) % m;
for (j = i
- 1; j > 0; j--)
d[j] = (d[j-1] * x + d[j]) % m;
d[0] = (d[0] + x) % m;
}
Находим
максимальное значение среди элементов массива d и сохраняем его в переменную res.
res = 0;
for (i = 0; i < n; i++)
if (d[i]
> res) res = d[i];
Выводим результат.
printf("%lld\n",res);
}