Пусть у вас есть массив A {Ai, 1 <= i <= n }
F(i)
- Максимальная сумма подмассива Aj { 1 <= j <= i }
, тогда
F(0) = 0
- пустой подмассив
F(1) = A(1)
- только первый элемент
F(i) = max(F(i-2) + A(i), F(i-1)) , 2 <= i <= n
F(n)
- ответ
Реализация С++:
int GetMaximumSubarraySum(const vector<int>& a)
{
// note that vector a have 1-based index
vector<int> v(a.size());
v[0] = 0;
v[1] = a[1];
for(int i =2; i < a.size(); i++)
v[i] = max(v[i-2] + a[i], v[i-1]);
return v.back();
}
Пояснение:
Во-первых, основная идея заключается в использовании динамического программирования. Мы пытаемся решить задачу для массива с N элементом, используя известный ответ для массива с N-1
и N-2
первыми элементами. Если N = 0
, ответ 0
, а если N = 1
, ответ A[1]
. Ясно. Для N >= 2
у нас есть 2 разных способа:
Используйте элемент A[N],
, тогда ответ будет A[N] + F[N-2]
(поскольку мы не можем использовать элемент A[N-1], а F[N-2]
является лучшим решением для подмассива 1..N-2
, нас не волнует, используется элемент F[N-2]
или нет, это просто лучшее решение для подмассива 1..N-2
.
Не используйте элемент A[N]
, тогда ответ будет F[N-1]
(потому что мы можем использовать элемент A[N-1], а F[N-1]
— лучшее решение для подмассива 1..N-1
, также нас не волнует, используется элемент F[N-1]
или нет.
Итак, нам нужно получить максимум из этих двух ситуаций. Для решения задачи нужно посчитать F[N]
в порядке возрастания и запомнить ответы.
Посмотрим на вашем примере:
[12, 8, 9, 10]
F[0] = 0
F[1] = 12
- использовать 1-й элемент
F[2] = max(F[0]+A[2], F[1]) = max(8, 12) = 12
- использовать 1-й элемент
F[3] = max(F[1]+A[3], F[2]) = max(21, 12) = 21
- использовать 1-й, 3-й элемент
F[4] = max(F[2]+A[4], F[3]) = max(22, 21) = 22
- использовать 1-й, 4-й элемент
Ответ F[4] = 22
.
04.11.2011
F[i]
, который сообщает мне максимальное значение подмассива данного массива, A, из A 1-е значение к его ith значению. :) Кажется, теперь я это понял... теперь я попробую написать для него код разными способами. Индекс на основе 1 тоже интересен. Я привык к индексам, начинающимся с 0. 10.11.2011