10. Советы по решению задач
8 апреля 2026 г.
Перебор
- Полный перебор – самый плохой класс алгоритмов, следует применять, если нет ничего лучше
- Начинайте с самого простого алгоритма, понижайте сложность усложняясь постепенно
- Определитесь с видом перебора, один из вариантов может быть гораздо эффективнее другого:
- Фильтрация – отсечением неподходящих вариантов
- Генерация – созданием подходящих вариантов
- Сокращайте пространство поиска как можно раньше
- Используйте симметрию для уменьшения перебора
- Используйте предварительные вычисления или кэширование
- Попробуйте решить задачу "с конца"
- Оптимизируйте всё, что можно
- Используйте лучшие структуры данных
Перебор с возвратом / Метод ветвей и границ / Backtrack
- Сокращайте пространство поиска как можно раньше
- Постарайтесь не использовать рекурсию
Разделяй и властвуй
Алгоритм решения
- Разбейте задачу на подзадачи
- Решите подзадачу
- Объедините и получите решение
- ВАЖНО: Подзадачи независимы друг от друга
Особенности
- Там, где можно применить этот метод, есть "скрытые деревья"
- Основная сложность состоит в том, что нужно увидеть зависимость целого от части
- Чаще всего разбиение происходит на 2 части
- Разделение должно происходить на примерно равные подзадачи
Жадные алгоритмы
Итеративно решаете и надеетесь, что всё получится
Особенности
- Легко придумать
- Легко оценить сложность
- Трудно оценить правильность
Свойства решения
- Оптимальное решение зависит от подоптимального
- Если оптимальный выбор делается на шаге, то он точно приведёт к оптимальному решению
Советы
- Если входные данные малого размера, то к задаче вряд ли применяется данный подход
- Если при сдаче получен статус WA (Wrong Answer), то задача решается другим методом
- Жадные алгоритмы часто видны при сортировке данных
- Большинство задач, решаемые данным способом, классические знание этих задач упрощает решение
Динамическое программирование (ДП)
Основные свойства
- Оптимальное решение зависит от подоптимального
- Существуют перекрывающиеся задачи
Советы
- Данный подход часто помогает перейти от перестановок к подмножествам
Типы построения решения
- Восходящее
| Плюсы | Минусы |
|---|---|
| Быстрее, если много подзадач выполняются несколько раз, т.к. нет затрат на рекурсивные вызовы | Для программистов, склонных к использованию рекурсии, этот стиль может быть не интуитивно понятным |
| Может сэкономить место в памяти при использовании метода "экономии места" | Если имеется n состояний, восходящее ДП проходит снизу вверх и заполняет значение всех этих n состояний |
- Нисходящее
| Плюсы | Минусы |
|---|---|
| Естественное преобразование из рекурсии полного перебора | Работает медленнее, если многие подзадаи выполняются повторно (из-за накладных расходов на вызовы функций) |
| Переход к выполнению подзадач только в случае необходимости (иногда это быстрее) | Ограничение глубины стека |
| Если имеется n состояний, то требуется O(n) памяти, что может привести к превышению лимита памяти |
AdHoc / Сложные / Специфические
Обычно необходимо просто знать решение задачи этого класса. Или придумать решение задачи на ходу. Очень часть один из гробов.
Математика / Вычислительная геометрия
Для закрытия данного класса задач необходимо решать задачи на ProjectEuler и читать соответствующие книги.
Рекомендации по книгам
По спортивному программированию
- Халим С. "Спортивное программирование"
- Лааксонен А. "Олимпиадное программирование"
- Скина С. "Олимпиадные задачи по программированию"
- Долинский М. "Решение сложных и олимпиадных задач по программированию"
По алгоритмам
- Бхаргава А. "Грокаем алгоритмы"
- Окулов С. "Динамическое программирование"
- Окулов С. "Программирование в алгоритмах"
- Кормен Т. "Алгоритмы. Вводный курс"
- Кормен Т. "Алгоритмы. Построение и анализ"
- Скиена С. "Алгоритмы. Руководство по разработке"
- Седжвик Р. "Алгоритмы на Java"
- Кнут Д. "Искусство программирования" (7 томов)