Жадный алгоритм

На каждом шаге берём то, что лучше всего сейчас, и не пересматриваем выбор. Это намного быстрее перебора, но работает только там, где выгодный сейчас шаг не мешает лучшему ответу в целом.

P22 Жадный алгоритм1×

Пример задачи: можно ли дойти до последнего индекса [1, 3, 1, 0, 2, 0, 0, 3], если каждое число — самый длинный прыжок с этого индекса.

0113213042506073reach
пока недостижимдостижимтекущий индекс iпройденнедостижим

Пока достижим только индекс 0

reach = 0i = –
01/26
сначала · назад · пуск · шаг
Скорость
1function canJump(nums):
2 reach = 0
3 for i from 0 to len(nums) - 1:
4 if i > reach:
5 break
6 reach = max(reach, i + nums[i])
7 return reach >= len(nums) - 1

← → шаг · пробел — пауза

Как узнать

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

Как решать такие задачи

  1. Назови выбор, который делаешь на каждом шаге: самый дальний прыжок, самый ранний конец, самый дешёвый вариант.
  2. Проверь, что он безопасен: замена на любой другой выбор не даёт ответа лучше. Если даёт, нужно динамическое программирование.
  3. Если выбор зависит от порядка, сначала отсортируй: по времени конца, по дедлайну, по размеру.
  4. Сделай один проход с одним текущим значением и остановись, как только ответ ясен.

Где встречается

  • Сжатие. Код Хаффмана в zip, gzip и PNG строится жадно: два самых редких символа склеивают в один, и так снова и снова. Частые символы получают короткие коды, редкие — длинные.
  • Маршрутизация. Роутеры с протоколом OSPF строят кратчайшие пути алгоритмом Дейкстры: каждый раз окончательно фиксируют ближайшую ещё не зафиксированную точку и больше к ней не возвращаются.