— Bessinin ilk dəqiqə ərzində qaça biləcəyi maksimal məsafə olsun, bu şərtlə ki, bu dəqiqədən sonra onun yorğunluq əmsalı -a bərabər olsun.
Məşqin başlanğıcına qədər dəqiqə keçib, ona görə də dp[0] = 0 qəbul edirik.
-ni hesablamaq üçün iki variantı nəzərdən keçirək:
Əgər ilk i - 1 dəqiqədən sonra Bessinin yorğunluq əmsalı artıq -a bərabərdirsə, o sadəcə daha bir dəqiqə istirahət edə bilər:
Fərz edək ki, Bessi son dəqiqəni aşağıdakı kimi keçirib:
Bu dəqiqədən sonra yorğunluq əmsalı yenidən -a bərabər olur. Bu blokun başlanğıcına qədər Bessi artıq məşqin ilk i - 2k dəqiqəsini keçirib, ona görə də bu ana qədər onun qaça biləcəyi maksimal məsafə dp[i - 2k]-yə bərabərdir.
Blokun ilk dəqiqəsi ərzində Bessi qaçır və aşağıdakı məsafəni qət edir
burada
Sonrakı dəqiqə Bessi istirahət edir. İstirahət zamanı məsafə artmır, lakin yorğunluq əmsalı tədricən -a qədər azalır.
Beləliklə,
Alqoritmin realizasiyası
İşçi massivləri elan edək:
— əgər Bessi qaçmağa qərar verərsə, -ci dəqiqədə nə qədər məsafə qət edəcəyini saxlayır.
— massivinin ilk elementinin cəmini saxlayır.
— Bessinin ilk dəqiqə ərzində qaça biləcəyi maksimal məsafəni saxlayır, bu şərtlə ki, bu dəqiqədən sonra onun yorğunluq əmsalı -a bərabər olsun.
#define MAX 10001
int d[MAX], sum[MAX], dp[MAX];Giriş məlumatlarını oxuyuruq.
scanf("%d %d", \&n, \&m);
for (i = 0; i \< n; i++)
scanf("%d", \&d[i]);massivinin prefiks cəmlərini hesablayırıq.
sum[0] = 0;
for (i = 1; i \<= n; i++)
sum[i] = sum[i - 1] + d[i - 1];-ın başlanğıc qiymətini təyin edirik.
dp[0] = 0;dp[1], dp[2], ..., dp[n] qiymətlərini ardıcıl olaraq hesablayırıq.
for (i = 1; i \<= n; i++)
{Əgər -ci dəqiqədə Bessi istirahət edirsə, onda dp[i] = dp[i - 1].
dp[i] = dp[i - 1];-ci dəqiqədə uzunluğu olan blok başa çatır ( dəqiqə qaçış və dəqiqə istirahət). Yorğunluq əmsalı -dən çox ola bilməz. Blokun özü bu dəqiqəyə sığmalıdır, ona görə də 2k \le i.
for (k = 1; k \<= m \&\& 2 * k \<= i; k++)
{Son blokun ilk dəqiqəsində Bessinin qət etdiyi runSum məsafəsini hesablayırıq.
int runSum = sum[i - k] - sum[i - 2 * k];Cari üçün əldə edilmiş optimal məsafəni hesablayırıq və -nin qiymətini yeniləyirik.
int temp = dp[i - 2 * k] + runSum;
if (temp \> dp[i]) dp[i] = temp;
}
}Cavabı çap edirik.
printf("%d\n", dp[n]);