Running#10152

Running (Razlaga rešitve)

Let be the maximum distance Bessie can run during the first minutes, provided that her fatigue level is exactly after these minutes.

Before the workout begins, minutes have passed, so we set dp[0] = 0.

To compute , consider two cases:

  1. If Bessie's fatigue level is already after the first i - 1 minutes, she can simply rest for one more minute:

    dp[i] = dp[i - 1]
  2. Suppose that Bessie spends the last minutes as follows:

After these minutes, the fatigue coefficient becomes again. Before the beginning of this block, Bessie has already completed the first i - 2k minutes of training, so the maximum distance she could have run by this point is dp[i - 2k].

During the first minutes of the block, Bessie runs and covers the distance

d[i − 2k + 1] + d[i − 2k + 2] + ... + d[i - k] = sum[i - k] - sum[i - 2k],

where

sum[i] = d[1] + d[2] + ... + d[i]

During the next minutes, Bessie rests. Her distance does not increase during the rest period, while the fatigue coefficient gradually decreases to .

Thus,

dp[i] = \max\left(dp[i-1], \max_{\substack{1 \le k \le m \\ 2k \le i}} \left(dp[i-2k] + sum[i-k] - sum[i-2k]\right)\right)

Algorithm implementation

Let us define the following arrays:

#define MAX 10001
int d[MAX], sum[MAX], dp[MAX];

Read the input data.

scanf("%d %d", &n, &m);
for (i = 0; i < n; i++)
  scanf("%d", &d[i]);

Compute the prefix sums of array .

sum[0] = 0;
for (i = 1; i <= n; i++)
  sum[i] = sum[i - 1] + d[i - 1];

Initialize the initial value of .

dp[0] = 0;

Sequentially compute the values dp[1], dp[2], ..., dp[n].

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

If Bessie rests during minute , then dp[i] = dp[i - 1].

  dp[i] = dp[i - 1];

At minute , a block of length ( minutes of running followed by minutes of rest) may end. The fatigue coefficient cannot exceed . Since the entire block must fit within these minutes, we must have 2k \le i.

  for (k = 1; k <= m && 2 * k <= i; k++)
  {

Compute the distance runSum that Bessie runs during the first minutes of the last block.

    int runSum = sum[i - k] - sum[i - 2 * k];

For the current compute the resulting optimal distance and update .

    int temp = dp[i - 2 * k] + runSum;
    if (temp > dp[i]) dp[i] = temp;
  }
}

Print the answer.

printf("%d\n", dp[n]);