Sia — la distanza massima che Bessie può percorrere nei primi minuti, a condizione che dopo questi minuti il suo coefficiente di stanchezza sia uguale a .
Prima dell'inizio dell'allenamento sono trascorsi minuti, quindi poniamo dp[0] = 0.
Per calcolare consideriamo due varianti:
Se dopo i primi i - 1 minuti il coefficiente di stanchezza di Bessie è già uguale a , allora essa può semplicemente riposare per un altro minuto:
Supponiamo che gli ultimi minuti Bessie li abbia trascorsi nel modo seguente:
Dopo questi minuti il coefficiente di stanchezza torna ad essere uguale a . Prima dell'inizio di questo blocco, Bessie ha già trascorso i primi i - 2k minuti dell'allenamento, quindi la distanza massima che poteva percorrere fino a quel momento è uguale a dp[i - 2k].
Durante i primi minuti del blocco Bessie corre e percorre la distanza
dove
Nei successivi minuti Bessie riposa. Durante il riposo la distanza non aumenta, mentre il coefficiente di stanchezza diminuisce gradualmente fino a .
Così,
Implementazione dell'algoritmo
Dichiariamo gli array di lavoro:
memorizza quanto Bessie percorrerà nel minuto , se decide di correre.
contiene la somma dei primi elementi dell'array .
contiene la distanza massima che Bessie può percorrere nei primi minuti, a condizione che dopo questi minuti il suo coefficiente di stanchezza sia uguale a .
#define MAX 10001
int d[MAX], sum[MAX], dp[MAX];Leggiamo i dati in ingresso.
scanf("%d %d", &n, &m);
for (i = 0; i < n; i++)
scanf("%d", &d[i]);Calcoliamo le somme prefisse dell'array .
sum[0] = 0;
for (i = 1; i <= n; i++)
sum[i] = sum[i - 1] + d[i - 1];Inizializziamo il valore iniziale .
dp[0] = 0;Calcoliamo in sequenza i valori dp[1], dp[2], ..., dp[n].
for (i = 1; i <= n; i++)
{Se al minuto Bessie riposa, allora dp[i] = dp[i - 1].
dp[i] = dp[i - 1];Al minuto si conclude un blocco di lunghezza ( minuti di corsa e minuti di riposo). Il coefficiente di stanchezza non può superare . Poiché il blocco stesso deve rientrare in questi minuti, allora 2k \le i.
for (k = 1; k <= m && 2 * k <= i; k++)
{Calcoliamo la distanza runSum, che Bessie ha percorso nei primi minuti dell'ultimo blocco.
int runSum = sum[i - k] - sum[i - 2 * k];Per il corrente calcoliamo la distanza ottimale ottenuta e aggiorniamo il valore di .
int temp = dp[i - 2 * k] + runSum;
if (temp > dp[i]) dp[i] = temp;
}
}Stampiamo la risposta.
printf("%d\n", dp[n]);