ENIGMA AI
ENIGMA AI

В чем заключается суть задачи о рюкзаке (Knapsack problem) и как выбор предметов влияет на заполнение ограниченного пространства?

встречается 1× middle algorithms

Как ответить

Суть задачи о рюкзаке — выбрать подмножество предметов с заданными весом и стоимостью так, чтобы суммарный вес не превышал вместимость, а суммарная стоимость была максимальной. Выбор каждого предмета напрямую влияет на заполнение пространства: более тяжёлый предмет может вытеснить несколько лёгких, поэтому нужно балансировать между весом и ценностью. Самая распространённая версия — 0/1 рюкзак (каждый предмет берётся целиком или не берётся), решается динамическим программированием.

Реализация на Python для 0/1 рюкзака:

def knapsack_01(weights, values, capacity):
    n = len(weights)
    dp = [[0] * (capacity + 1) for _ in range(n + 1)]
    for i in range(1, n + 1):
        w = weights[i-1]
        v = values[i-1]
        for c in range(capacity + 1):
            if w > c:
                dp[i][c] = dp[i-1][c]
            else:
                dp[i][c] = max(dp[i-1][c], dp[i-1][c-w] + v)
    return dp[n][capacity]

Ключевой момент: dp[i][c] — максимальная стоимость для первых i предметов при вместимости c. Выбор предмета i либо не меняет заполнение (если не брать), либо занимает w единиц пространства и добавляет v к стоимости (если взять). Перебор всех комбинаций неявный за счёт сохранения лучших результатов для каждой вместимости.

Влияние выбора на заполнение:

  • Если предмет имеет большой вес и малую стоимость, его брать невыгодно — он занимает место, которое могли бы занять более ценные лёгкие предметы.
  • При одинаковой стоимости на единицу веса жадный алгоритм (брать предметы с максимальной удельной стоимостью) даёт оптимальное решение только для дробного рюкзака, где можно брать части предметов. Для 0/1 жадность не гарантирует оптимум — нужно DP.
  • Ограничение пространства создаёт конкуренцию: два предмета с суммарным весом ≤ capacity, но один из них может быть исключён, если вместе с другим даёт большую стоимость, чем третий тяжёлый предмет.

Пример: weights = [2,3,4], values = [3,4,5], capacity = 5. DP найдёт, что оптимально взять предметы с весом 2 и 3 (стоимость 7), а не один тяжёлый вес 4 (стоимость 5). Выбор первого предмета (вес 2) оставляет 3 единицы места, куда помещается второй предмет (вес 3), итого 5 — максимум.

На собеседовании важно показать понимание рекуррентной формулы, сложность O(n*capacity) по времени и памяти, а также возможность оптимизации памяти до O(capacity) с использованием одномерного массива (перебор вместимости справа налево для 0/1).

Ключевые тезисы

  • Задача комбинаторной оптимизации: максимизация стоимости при ограничении на суммарный вес.
  • Для 0/1 рюкзака применяется динамическое программирование с рекуррентным соотношением dp[i][c] = max(dp[i-1][c], dp[i-1][c-w] + v).
  • Выбор предметов влияет на заполнение: каждый предмет занимает конкретное место, что может блокировать более выгодные комбинации.
  • Жадный алгоритм не работает для 0/1 варианта, так как оптимальное решение может включать предмет с худшей удельной стоимостью, если это позволяет взять другой ценный предмет.
  • Сложность по времени O(n*capacity), по памяти можно снизить до O(capacity) с помощью одномерного DP.

Что спросят дальше

  • — Как изменится решение, если предметы можно брать неограниченное количество раз (unbounded knapsack)?
  • — Можно ли решить задачу с вещественными весами и стоимостью?
  • — Приведите пример, когда жадный алгоритм даёт неоптимальное решение для 0/1 рюкзака.

Готовьтесь к собеседованию с ENIGMA AI

AI-суфлёр подсказывает ответы прямо на собеседовании в реальном времени — незаметно для интервьюера.

Скачать приложение