1559. Избирательная система

 

Студенты Байтляндского университета для занятий используют автоматическую систему регистрации. Регистрация открыта определенный период времени. При этом каждый момент времени имеет характеристику, которая описывается положительным числом. Входить в систему можно не более k раз, каждый вход может длиться не более d единиц времени. Периоды нахождения в системе не должны пересекаться.

Имеется строка, i - ый символ которой описывает характеристику в i - ый момент времени. Характеристика задается буквами от ‘a’ до ‘z’, обозначающих соответственно числа от 1 до 26. Необходимо разработать стратегию входа в систему, для которой сумма характеристик во время нахождения в системе наибольшая.

 

Вход. Первая строка каждого теста содержит значения d и k (1 ≤ d, k ≤ 1000). Вторая содержит строку, состоящую из не более чем 1000 букв a z.

 

Выход. Для каждого теста в отдельной строке выведите наибольшую возможную сумму характеристик.

 

Пример входа

4 1

acacca

2 2

cabcca

2 18

yptcsevnuzlsrfjxurpslztlinhddelpitmvaezowjcfjjfgmfq

 

Пример выхода

10

10

598

 

 

РЕШЕНИЕ

динамическое программирование

 

Анализ алгоритма

В ячейках s[i] будем хранить сумму характеристик всех моментов времени от 1 до i – го (префиксные суммы). В dp[i][j] будет находиться наибольшая возможная сумма характеристик периодов времен при условии, что уже прошло i единиц времени, а в систему входили в точности j раз.

Рассмотрим два случая:

·        Если в i - ый момент времени студент не находится в системе, то dp[i][j] = dp[i – 1][j]. Это означает, что j раз входили в систему в период до (i – 1)-ой единицы времени включительно.

·        Поскольку значения всех характеристик положительны, то чем больше мы будем в системе, тем большей будет сумма характеристик. Если в i - ый момент времени студент находится в системе, то считаем, что вошел он туда в (id + 1) - ый момент времени. В  этом случае

dp[i][j] = dp[id][j – 1] + s[i] – s[id]

Заметим, что разница s[i] – s[id] равна сумме характеристик с (id + 1) - го по i - ый момент времени. Например, при d = 2, i = 5, s[5] – s[3] содержит сумму характеристик для 4 и 5 момента времени.

 

Тогда имеет место соотношение:

dp[i][j] = max{dp[id][j – 1] + s[i] – s[id], dp[i – 1][j]}

При этом значение id считается равным нулю, если id < 0.

 

Также отметим, что dp[i][0] = 0, так как если в систему не входили ни одного раза, то максимальная сумма характеристик равна нулю.

 

Пример

Рассмотрим второй пример, в котором d = 2, k = 2. По строке cabcca заполним массив s:

 

Поскольку длина строки равна 6, а k = 2, то размер массива dp будет 6 на 2. Следующая таблица содержит значения ячеек двумерного массива dp[i][j].

 

Например:

dp[4][1] = max{dp[2][0] + s[4] – s[2], dp[3][1]} =

max{0 + 94, 4} = max{5, 4} = 5

 

dp[5][2] = max{dp[3][1] + s[5] – s[3], dp[4][2]} =

max{4 + 12 – 6, 9} = max{10, 9} = 10

 

Поскольку максимум достигается на значении dp[3][1] + s[5] – s[3], то студенту в момент времени 5 выгоднее быть в системе. То есть его второе вхождение в систему (когда прошло еще не более пяти секунд) должно происходить в моменты времени 4 и 5.

 

Реализация алгоритма

Объявим рабочие массивы.

 

int s[1001], dp[1001][1001];

 

Функция maximalGoodness возвращает наибольшую возможную сумму характеристик.

 

int maximalGoodness(int d, int k)

{

  int i, j, temp, n = str.size();

 

Вычислим сумму характеристик всех моментов времени от 1 до i - го и занесем ее в s[i].

 

  memset(s,0,sizeof(s));

  for(i = 1; i <= n; i++)

    s[i] = s[i-1] + str[i-1] - 'a' + 1;

 

Вычисляем значения dp[i][j].

 

  memset(dp,0,sizeof(dp));

  for(i = 1; i <= n; i++)

    for(j = 1; j <= k; j++)

    {

      temp = (i - d) < 0 ? 0 : i - d;

      dp[i][j] = max(dp[i-1][j],dp[temp][j-1] + s[i] - s[temp]);

    }

  return dp[n][k];

}

 

Основная часть программы. Обрабатываем несколько тестов.

 

while (cin >> d >> k)

{

  cin >> str;

  res = maximalGoodness(d, k);

  cout << res << endl;

}