Нехай — максимальна відстань, яку Бессі може пробігти за перші хвилин за умови, що після цих хвилин її коефіцієнт втоми дорівнює .
До початку тренування пройшло хвилин, тому покладемо dp[0] = 0.
Для обчислення розглянемо два варіанти:
Якщо після перших i - 1 хвилин коефіцієнт втоми Бессі вже дорівнює , то вона може просто відпочити ще одну хвилину:
Припустимо, що останні хвилин Бессі провела наступним чином:
Після цих хвилин коефіцієнт втоми знову стає рівним . До початку цього блоку Бессі вже провела перші i - 2k хвилин тренування, тому максимальна відстань, яку вона могла пробігти до цього моменту, дорівнює dp[i - 2k].
Протягом перших хвилин блоку Бессі біжить і долає відстань
де
Наступні хвилин Бессі відпочиває. За час відпочинку відстань не збільшується, а коефіцієнт втоми поступово зменшується до .
Таким чином,
Реалізація алгоритму
Оголосимо робочі масиви:
зберігає, скільки Бессі пробіжить на хвилині , якщо вона вирішить бігти.
містить суму перших елементів масиву .
містить максимальну відстань, яку Бессі може пробігти за перші хвилин, за умови, що після цих хвилин її коефіцієнт втоми дорівнює .
#define MAX 10001
int d[MAX], sum[MAX], dp[MAX];Зчитуємо вхідні дані.
scanf("%d %d", &n, &m);
for (i = 0; i < n; i++)
scanf("%d", &d[i]);Обчислюємо префіксні суми масиву .
sum[0] = 0;
for (i = 1; i <= n; i++)
sum[i] = sum[i - 1] + d[i - 1];Ініціалізуємо початкове значення .
dp[0] = 0;Послідовно обчислюємо значення dp[1], dp[2], ..., dp[n].
for (i = 1; i <= n; i++)
{Якщо на хвилині Бессі відпочиває, то dp[i] = dp[i - 1].
dp[i] = dp[i - 1];На хвилині завершується блок довжини ( хвилин бігу та хвилин відпочинку). Коефіцієнт втоми не може перевищувати . Оскільки сам блок повинен вміщатися в ці хвилин, то 2k \le i.
for (k = 1; k <= m && 2 * k <= i; k++)
{Обчислюємо відстань runSum, яку Бессі пробігла за перші хвилин останнього блоку.
int runSum = sum[i - k] - sum[i - 2 * k];Для поточного обчислюємо отриману оптимальну відстань і оновлюємо значення .
int temp = dp[i - 2 * k] + runSum;
if (temp > dp[i]) dp[i] = temp;
}
}Виводимо відповідь.
printf("%d\n", dp[n]);