Запоминание всегда не приводит к асимптотической сложности времени за полиномиальное время.В первом подходе вы можете применить памятку, но это не уменьшит сложность времени до полиномиального времени.
Что такое памятование?
Проще говоря, памятование - это не что иное, как рекурсивное решение(сверху вниз), в котором хранится результат вычисленного решения подзадачи.И если эту же подзадачу нужно вычислить снова, вы возвращаете исходное сохраненное решение вместо его повторного вычисления.
Запоминание в вашем первом рекурсивном решении
В вашем случае каждая подзадача имеет видпоиск оптимального выбора видов деятельности для подмножества.Так что памятка (в вашем случае) приведет к сохранению оптимального решения для всех подмножеств.
Без сомнения, памятка даст вам повышение производительности, избегая повторного вычисления решения на подмножестве действий.это было «замечено» ранее, но оно не может (в этом случае) уменьшить сложность времени до полиномиального времени, потому что вы в конечном итоге сохраняете подрешения для каждого подмножества (в худшем случае).
ГдеПамятка дает нам реальную выгоду?
С другой стороны, если вы видите this , где памятка применяется для рядов Фибоначчи, общее количество подрешения, которое вы должны сохранить, является линейнымс размером ввода.И, таким образом, это уменьшает экспоненциальную сложность до линейной.
Как вы можете запомнить первое решение
Для применения запоминания в первом подходе вам необходимо поддерживать подрешения.Вы можете использовать структуру данных Map<Set<Activity>, Integer>
, в которой будет храниться максимальное количество совместимых действий для данного Set<Activity>
.В java equals()
на java.util.Set
работает правильно во всех реализациях, поэтому вы можете использовать его.
Ваш первый подход будет изменен следующим образом:
// this structure memoizes the sub-solutions
Map<Set<Activity>, Integer> map;
ActivitySelection(Set<Activity> activities) {
if(map contains activities)
return map.getValueFor(activities);
let max = 0
for (a: activities):
let B = {Activities - allIncompatbleWith(a)}
let maxOfSubproblem = ActivitySelection(B)
max = max (max, maxOfSubproblem+1)
map.put(activities, max)
return max
}
На более легкой ноте:
Временная сложность второго решения (CLRS 16.1) будет O(n^3)
вместо O(n^2)
.Вам нужно будет 3 петли для i
, j
и k
.Пространственная сложность для этого решения O(n^2)
.