Квартал без пустырей

тема: DP 2D · уровень: продвинутый

Условие

В городе Мун планируют построить новый квадратный квартал. На карте отмечены клетки, где уже есть коммуникации (1) и где их нет (0). Строить можно только на клетках с коммуникациями.

Градостроитель хочет выбрать самый большой *квадратный* участок, целиком состоящий из единиц.

Найдите длину стороны максимального квадрата из единиц.

Формат ввода

В первой строке даны два целых числа m и n — размеры карты (m строк и n столбцов). Далее идут m строк, каждая содержит ровно n символов 0 или 1 (без пробелов).

Формат вывода

Выведите одно целое число — максимальную возможную длину стороны квадрата, составленного только из 1.

Ограничения

Пример

Ввод:

4 5
11110
11010
11110
01111

Вывод:

2

Как решать — идея подхода

Приём: Динамическое программирование (максимальный квадрат) + свёртка до 1D

Ключевое наблюдение: квадрат из единиц удобно «наращивать» по одному слою. Если в клетке (i, j) стоит 1, то квадрат с правым нижним углом в этой клетке может быть на 1 больше, чем минимальный из трёх соседних квадратов: сверху, слева и по диагонали сверху-слева. Если хотя бы один из них маленький, больший квадрат всё равно не соберётся (в одном из направлений не хватит единиц).

Приём: динамическое программирование по клеткам. Определим dp[i][j] — максимальная сторона квадрата из 1, у которого правый нижний угол в (i, j). Переход:

Ответ — максимум по всем dp.

План решения:

Сложность: O(m*n) по времени, память O(n) (или O(m*n), если хранить всю таблицу).

Частая ошибка: неправильно обновить диагональный элемент при 1D-таблице. Нужна временная переменная: сначала запомнить старое dp[j] (это «сверху»), а «диагонь» брать из значения, которое было dp[j-1] в предыдущей строке.

Решить задачу с автопроверкой на Python →

Куда дальше