
First compute partial sums, so that psum [i] = E0 + ... + Ei-1. Then, if we let dp [i] be the best possible total over all subsets of the first i cows, since we can choose at most K cows in a row we have the following recurrence:
dp [i] = max over all j such that i - K <= j <= i of dp [j - 1] + Ej + ... + Ei-1 = dp [j - 1] + psum [i] - psum [j].
This immediately gives us an O(NK) solution. However, note that the psum [i] term is independent of j, while dp [j - 1] - psum [j] depends only on j. Thus, we can store paired values of (dp [j - 1] - psum [j], j) in a heap, which allows us to quickly compute the maximum value of dp [j - 1] - psum [j] for j >= i - K in an amortized fashion. (In particular, we have a max heap sorted by dp [j - 1] - psum [j], and each time we perform a query we pop the heap until the index of the top is at least i - K.) This gives us an O(N log N) solution:
#include <cstdio>
#include <queue>
using namespace std;
FILE *fin = fopen ("mowlawn.in", "r"), *fout = fopen ("mowlawn.out", "w");
const int MAXN = 100005;
struct data
{
int ind;
long long val;
inline bool operator < (const data &o) const
{
return val < o.val;
}
};
int N, K;
long long psum [MAXN], dp [MAXN];
priority_queue <data> hp;
int main ()
{
fscanf (fin, "%d %d", &N, &K);
for (int cow, i = psum [0] = 0; i < N; i++)
{
fscanf (fin, "%d", &cow);
psum [i + 1] = psum [i] + cow;
}
hp.push ((data) {-1, 0});
for (int i = 0; i <= N; i++)
{
while (hp.top ().ind < i - K - 1)
hp.pop ();
dp [i] = hp.top ().val + psum [i];
hp.push ((data) {i, dp [i] - psum [i + 1]});
}
fprintf (fout, "%lld\n", dp [N]);
return 0;
}