Взгляните на это: Динамическое программирование - Самый большой квадратный блок
По сути, учитывая прямоугольники, вы добавляете препятствие и удаляете квадрат, которому мешает препятствие.
Затем запустите связанный алгоритм (с «ограничителями», являющимися препятствиями и существующими квадратами), и если будет найдено место, которое может соответствовать квадрату размера NxN (N - большая часть прямоугольника), и добавьте прямоугольник) .
Это можно оптимизировать немного дальше, и я доверяю вам это. (По сути - прямоугольники не всегда будут располагаться в наиболее оптимальном месте. Это можно исправить, по крайней мере, до некоторой степени)
Это решение даст вам O (n) время и пространство для каждого добавленного препятствия.
Возможные модификации, которые вы также должны рассмотреть: не перестраивайте массив для каждого препятствия, но постройте его для массива пустот препятствий и изменяйте его по мере продвижения. Это сохранит прохождение всего массива для каждого препятствия.