Qutuları birincidən başlayaraq yenidən nömrələyək (-ci qutu a_i xalını ehtiva edir). Gəlin funksiyasını -dən -ci qutuya qədər olan qutuları daxil edərək əldə edilə bilən maksimal xal cəmi kimi təyin edək.
Onda:
f(1) = a_1,
f(2) = max(a_1, a_2)
hesablarkən iki halı nəzərdən keçirək:
əgər -ci qutu seçilibsə, onda qonşu (i - 1)-ci qutu əlçatmazdır. Bu halda maksimal xal cəmi f(i - 2) + a_i olacaq.
əgər -ci qutu seçilmirsə, onda maksimal xal cəmi f(i - 1) olacaq.
Beləliklə
-nin qiymətlərini kütləsində saxlayacağıq. Problemin cavabı f(n) = res[n] olacaq.
Nümunə
f(3) hesablanmasını nəzərdən keçirək
Əgər üçüncü qutunu açmasaq, sadəcə iki qutu üçün ən yaxşı nəticəni alacağıq: f(2) = 6.
Əgər üçüncü qutunu açsaq, onda ikinci açılabilməz (onlar qonşudur). Deməli, birinci qutu üçün optimal nəticəni götürüb üçüncü qutunun xalını əlavə edə bilərik:
İki variantdan maksimumu seçirik:
f(4) hesablanmasını nəzərdən keçirək
Əgər dördüncü qutunu açmasaq, nəticə f(3) = 8 olacaq.
Əgər dördüncü qutunu açsaq, üçüncüsü açılabilməz. Deməli, ilk iki qutu üçün ən yaxşı nəticəni alıb dördüncü qutudan xalları əlavə edirik:
İki variantdan maksimumu seçirik:
Məşq
Aşağıdakı giriş məlumatları üçün -nin qiymətlərini hesablayın:
Alqoritmin reallaşdırılması
Gəlin giriş kütləsi və nəticə kütləsi elan edək.
#define MAX 1000001
long long a[MAX], res[MAX];Giriş məlumatlarını oxuyuruq.
scanf("%d",&n);
for (i = 1; i <= n; i++)
scanf("%lld",&a[i]);Bir res_1 və iki res_2 qutu üçün cavabı hesablayırıq.
res[1] = a[1];
if (n > 1) res[2] = max(a[1],a[2]);Qalan qutular üçün cavabları hesablayırıq.
for (i = 3; i <= n; i++)
res[i] = max(res[i - 2] + a[i], res[i - 1]);Cavabı çıxışa veririk.
printf("%lld\n",res[n]);Java reallaşdırılması
import java.util.*;
class Main
{
static long a[] = new long[1000001];
static long res[] = new long[1000001];
public static void main(String[] args)
{
Scanner con = new Scanner(System.in);
int n = con.nextInt();
for (int i = 1; i <= n; i++)
a[i] = con.nextInt();
res[1] = a[1];
if (n > 1) res[2] = Math.max(a[1],a[2]);
for (int i = 3; i <= n; i++)
res[i] = Math.max(res[i - 2] + a[i], res[i - 1]);
System.out.println(res[n]);
con.close();
}
}Python reallaşdırılması
Giriş məlumatlarını oxuyuruq.
n = int(input())
lst = list(map(int,input().split()))siyahısını başlatırıq.
dp = [0] * len(lst)Bir dp_0 və iki dp_1 qutu üçün cavabı hesablayırıq.
dp[0] = lst[0]
if (n > 1): dp[1] = max(lst[0], lst[1])Qalan qutular üçün cavabları hesablayırıq.
for i in range(2, len(lst)):
dp[i] = max(dp[i-1], dp[i-2] + lst[i])Cavabı çıxışa veririk.
print(dp[-1])