Алгоритм для подвектора минимальной суммы

Проблема, обнаруженная в столбце 8 программных жемчужин, выглядит следующим образом:

По заданному вещественному вектору x[n] вычислить максимальную сумму, найденную в любом непрерывном подвекторе.

Предоставленное окончательное решение имеет сложность O (n), которая выглядит следующим образом:

std::vector<int> x;
int max_so_far = 0;
int max_here = 0;
for (std::size_t i = 0; i < x.size(); ++i)
{
   max_here = std::max(max_here + x[i], 0);
   max_so_far = std::max(max_so_far, max_here);
}

Я хотел бы знать, как изменить приведенный выше алгоритм, чтобы обеспечить минимальную сумму.


person Community    schedule 07.02.2011    source источник
comment
Установите x[n] = -x[n] и запустите максимальную сумму...   -  person    schedule 08.02.2011
comment
Вы можете умножить все элементы вектора на -1, запустить вектор через приведенный выше код и снова умножить найденную сумму на -1.   -  person toochin    schedule 08.02.2011
comment
@Reyzooti - у меня есть сомнения. Включает ли термин «подвектор» только векторы, начинающиеся с позиции 0?   -  person Neo    schedule 08.02.2011
comment
Если ваш вектор содержит все отрицательные числа, ваш код не будет работать. Он сообщит, что максимальное значение равно 0. Исправьте это, сделав начальное значение max_so_far равным наименьшему целому числу.   -  person Jim Mischel    schedule 08.02.2011
comment
@Jim: я получил алгоритм отсюда: netlib.bell-labs. com/cm/cs/pearls/s08.pdf Значит, в печатной копии тоже должна быть ошибка?   -  person    schedule 08.02.2011
comment
@Jim: если подвектор может включать в себя подвектор нулевой длины, то 0 действительно является максимальной суммой, когда все числа отрицательны. Так что это правильно.   -  person DS.    schedule 08.02.2011


Ответы (1)


Вам нужно только инвертировать знак каждого элемента в x, а затем запустить алгоритм:

std::vector<int> x;
int max_so_far = 0;
int max_here = 0;

for (std::size_t i = 0; i < x.size(); ++i) x[i] = -x[i];

for (std::size_t i = 0; i < x.size(); ++i)
{
   max_here = std::max(max_here + x[i], 0);
   max_so_far = std::max(max_so_far, max_here);
}

int min_so_far = -max_so_far;
person Murilo Vasconcelos    schedule 07.02.2011
comment
Так не пойдет. max отрицательного, а ноль всегда будет равен нулю. - person Neo; 08.02.2011
comment
@Neo: да, из-за этого я перевернул знак элементов x. - person Murilo Vasconcelos; 08.02.2011
comment
@Придурок - Точно. Вот что меня смутило. - person Neo; 08.02.2011
comment
Если все элементы отрицательные, он вернет 0. Мы должны начать с max_so_far = max_here = -infinity... Конечно, вы можете рассматривать подвектор из никаких элементов как имея нулевую сумму, и считайте этот действительный вывод. - person ; 08.02.2011
comment
Максимальная сумма подмассива из 0 элементов равна 0, так как вы ничего не суммируете. - person Murilo Vasconcelos; 08.02.2011
comment
@MUrilo: Если у вас есть массив из 10 элементов, и вы рассмотрели подмассивы из ноль элементов, то алгоритм действителен. Возможно, мы говорим об одном и том же. Так или иначе... - person ; 08.02.2011