Обратите внимание, что я получил свое объяснение из этого ответа. Он демонстрирует, как алгоритм Кадане можно рассматривать как алгоритм DP, который имеет перекрывающиеся подзадачи.
Выявление подзадач и повторяющихся отношений
Представьте, что у нас есть массив a
, из которого мы хотим получить максимальный подмассив. Чтобы определить максимальный подмассив, который заканчивается индексом i
, выполняется следующее рекурсивное отношение:
max_subarray_to(i) = max(max_subarray_to(i - 1) + a[i], a[i])
Чтобы получить максимальный подмассив a
, нам нужно вычислить max_subarray_to()
для каждого индекса i
в a
, а затем взять из него max()
:
max_subarray = max( for i=1 to n max_subarray_to(i) )
Пример
Теперь предположим, что у нас есть массив [10, -12, 11, 9]
, из которого мы хотим получить максимальный подмассив. Это будет работа, необходимая для запуска алгоритма Кадане:
result = max(max_subarray_to(0), max_subarray_to(1), max_subarray_to(2), max_subarray_to(3))
max_subarray_to(0) = 10 # base case
max_subarray_to(1) = max(max_subarray_to(0) + (-12), -12)
max_subarray_to(2) = max(max_subarray_to(1) + 11, 11)
max_subarray_to(3) = max(max_subarray_to(2) + 9, 49)
Как видите, max_subarray_to()
оценивается дважды для каждого i
, кроме последнего индекса 3
, что показывает, что алгоритм Кадана действительно имеет перекрывающиеся подзадачи.
Алгоритм Кадана обычно реализуется с использованием подхода DP снизу вверх, чтобы воспользоваться преимуществами перекрывающихся подзадач и вычислить каждую подзадачу только один раз, следовательно, превратив ее в O (n).
person
arauter
schedule
23.10.2020
t = pow(x, n/2); return t*t;
. Если я вместо этого сделаюreturn pow(x,n/2)*pow(x,n/2)
, будет ли это DP или я просто глупый, если не сохраню возвращаемое значение рекурсивного вызова? - person IVlad   schedule 27.10.2020