Перенумеруємо коробки, починаючи з першої (-а коробка містить a_i очок). Нехай позначає максимальну суму очок, яку можна отримати, розглядаючи коробки з по -у включно.
Тоді:
f(1) = a_1,
f(2) = max(a_1, a_2)
При обчисленні розглянемо два випадки:
якщо обирається -а коробка, то сусідня (i - 1)-а коробка недоступна. У цьому випадку максимальна сума очок буде дорівнювати f(i - 2) + a_i.
якщо -а коробка не обирається, то максимальна сума очок дорівнює f(i - 1).
Таким чином
Запам'ятаємо значення в масиві . Відповіддю задачі буде значення f(n) = res[n].
Приклад
Розглянемо обчислення f(3)
Якщо третю коробку не відкривати, то ми просто отримаємо найкращий результат для перших двох коробок: f(2) = 6.
Якщо третю коробку відкрити, то другу відкрити вже не можна (вони сусідні). Отже, можна взяти оптимальний результат для першої коробки і додати очки з третьої:
Обираємо максимум з двох варіантів:
Розглянемо обчислення f(4)
Якщо четверту коробку не відкривати, то результат дорівнює f(3) = 8.
Якщо четверту коробку відкрити, то третю відкрити не можна. Отже, беремо найкращий результат для перших двох коробок і додаємо очки з четвертої:
Обираємо максимум з двох варіантів:
Вправа
Обчисліть значення для наступних вхідних даних:
Реалізація алгоритму
Оголосимо вхідний масив та результуючий .
#define MAX 1000001
long long a[MAX], res[MAX];Читаємо вхідні дані.
scanf("%d",&n);
for (i = 1; i <= n; i++)
scanf("%lld",&a[i]);Обчислюємо відповідь для однієї res_1 та двох res_2 коробок.
res[1] = a[1];
if (n > 1) res[2] = max(a[1],a[2]);Обчислюємо відповіді для решти коробок.
for (i = 3; i <= n; i++)
res[i] = max(res[i - 2] + a[i], res[i - 1]);Виводимо відповідь.
printf("%lld\n",res[n]);Java реалізація
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 реалізація
Читаємо вхідні дані.
n = int(input())
lst = list(map(int,input().split()))Ініціалізуємо список .
dp = [0] * len(lst)Обчислюємо відповідь для однієї dp_0 та двох dp_1 коробок.
dp[0] = lst[0]
if (n > 1): dp[1] = max(lst[0], lst[1])Обчислюємо відповіді для решти коробок.
for i in range(2, len(lst)):
dp[i] = max(dp[i-1], dp[i-2] + lst[i])Виводимо відповідь.
print(dp[-1])