Блог пользователя neosnova

Автор neosnova, история, 3 года назад, По-русски

Привет, Codeforces!

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

Дана квадратная таблица размером n на n (n<=1000). Каждая ячейка таблицы либо черная, либо белая. Надо посчитать количество способов выбрать 2 непересекающихся черных прямоугольника. Под черным прямоугольником понимается любая подтаблица (в форме прямоугольника или квадрата) данной матрицы содержащая более 1 клетки и заполненная только черными клетками.

Буду очень благодарен за любую подсказку.

Тест 1
Тест 2
Тест 3

P.S Во всех тестах C — черная клетка, B — белая.

  • Проголосовать: нравится
  • -4
  • Проголосовать: не нравится

»
3 года назад, скрыть # |
Rev. 4  
Проголосовать: нравится +1 Проголосовать: не нравится

Разобъём исходный прямоугольник на группы из чёрных полей(Группа чёрных клеток, для каждой из которых можно дойти из любой другой чёрной клетки по чёрным клеткам переходя по сторонам) с помощью BFSa, DFSa, тогда задача сводится к посчитать кол-во различных чёрных подпрямоугольников определенного поля. И для различных полей ответ будет суммой a[i] * a[j], где a[i] — кол-во различных подпрямоугольников на поле i, но тогда в худшем случае где полей n * n / 2 будет TL. Технически можно подсчитать кол-во одинаковых полей и для каждого такого поля решать по отдельности, домножая ответ в последствии a[i] * a[j] * cnt[i] * cnt[j] Если у нас получится решить такую подзадачу, то останется только посчитать кол-во вариантов выбрать два непересекающихся подпрямоугольника в одном поле.

»
3 года назад, скрыть # |
Rev. 2  
Проголосовать: нравится +1 Проголосовать: не нравится

Для каждой клетки (i, j) поля посчитаем две величины end[i][j] и start[i][j] — количество прямоугольников, для которых эта клетка является правым нижним углом и левым верхним соотвественно. Тогда просто пробежимся по всем клеткам поля и к ответу прибавим произведение end[i][j] на сумму S всех start[x][y], для которых x > i или y > j. Если научимся считать end[i][j], то сможем посчитать и start[i][j]. Попробуем научиться считать end[i][j]: зафиксируем i, насчитаем h[j] — высота непрерывного столбика из черных клеток над клеткой (i, j) (включая саму клетку). Для клетки (i, j) посмотрим всевозможные прямоугольники, которые в ней заканчиваются — окажется, что они образуют неубывающую лесенку (при возрастании номера столбца) и end[i][j] будет равно площади этой лесенки минус один. С помощью массивчика h легко поддерживать размер лесенки.

  • »
    »
    3 года назад, скрыть # ^ |
     
    Проголосовать: нравится 0 Проголосовать: не нравится

    UPD: это не совсем верно, некоторые пары прямоугольников посчитаются два раза. Чтобы обойти это, придётся считать не только end[i][j] и start[i][j], а ещё количество прямоугольников, для которых эта клетка является верхним правым и нижним левым углом