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

Автор Zlobober, 13 лет назад, По-русски

Специально по просьбе JKeeJ1e30.

Задачи второго дивизиона и A с B первого уже разбирались ранее, поэтому я опишу только решения C и D.

C. Петя и Пауки
Поначалу могло показаться, что это задача на конструктив, но такую мысль нужно сразу откидывать. Конструктивные решения ломались тестами 4 4, 7 4 и 5 6.
Если заметить, что nm ≤ 40, и понять, что доску можно вращать, то из простого рассуждения, что меньшая сторона доски не больше 6, становится ясно, что задача - на какую-то динамику по профилю.
Моё решение - такое. Будем считать не максимальное количество оставшихся клеток, а минимальное количество центров, в которые могут сбежаться все пауки. Повернём доску, чтобы количество строк было не больше шести.
Пусть D[k][pmsk][msk] - это минимальное количество центров, достаточное, чтобы собрать всех тараканов с первых k столбцов, причём k-ый столбец имеет маску pmsk, а k+1-ый - msk. Тогда за переход мы перебираем маску tmsk k-1-ого столбца, и среди тех, для которых k-ый столбец может целиком разбежаться по центрам, выбираем тот, для которого D[k - 1][tmsk][pmsk] минимально.
Получается решение за O(n * 23m), где n > m.
Другие варианты решения, которые я видел:
Можно как-то схлопнуть две двоичных маски в одну троичную, честно говоря, я не вникал, как именно.
Можно насчитать ответ для всех входных данных, благо тех совсем немного, каким-нибудь оптимизированным перебором. Например, перебирая маски центров в порядке возрастания количества бит.
D. Петя и раскраски.
Тут нужно посидеть, подумать, и вывести пару формул.
Во-первых, когда m = 1, ответ - kn, потому как подходит любая раскраска.

Когда m > 1, обратим наши взоры на два крайних столбца. Проведём прямую справа от левого крайнего столбца. Слева и справа от неё должно быть одинаковое количество цветов - пусть X. Теперь заметим, что если начать двигать эту прямую направо, количестов различных цветов слева будет неуменьшаться, а справа - неувеличиваться. А раз эти два количества должны оставаться одинаковыми, то ни одного увеличения/уменьшения происходить не должно. Значит все возможные цвета, которые могут оказаться слева от прямой должны присутствовать в крайнем левом столбце, а все возможные цвета, который могут оказаться справа от прямой - в крайнем правом столбце.

Иными словами, множество цветов на всей доске должно иметь вид , где |L| = |R|, а множество цветов в левом и правом столбце - L и R соответственно. При этом заметим, что в оставшихся столбцах могут присутствовать только цвета из - иначе нам поломает всё условие.

Что же, это даёт следующий алгоритм.

Зафиксируем и (должны выполняться условия 2x + y ≤ k и x + y ≤ n. Тогда во-первых, ответ нужно домножить на - это количество способов выбрать соответственно x, y и x цветов в множества .

Далее, все клетки между крайними столбцами можно покрасить в произвольный из y цветов, значит ответ домножается на kn(m - 2).

Потом, нам надо покрасить крайние столбцы. Количество способов покрасить столбец в x цветов так, чтобы все цвета присутствовали, считается динамикой D[x] следующим образом: . Наконец, ответ домножается на вышепосчитанное D[x]2.

С реализацией этого решения может быть некоторое количество проблем. Я лично столкнулся с тем, что оно адски тормозило. Оказалось фатальным делать O(k) взятий обратного элемента за логарифм в лонг лонгах. Помогли следующие оптимизации - предподсчитываем все биномиальные коэффициенты до 2000, расписываем как - последние два выражения у нас предподсчитаны. Можно было бы также просто предподсчитать обратные факториалы - у нас будет использоваться O(n) значений обратных факториалов.

Конкретно реализацию можно посмотреть в моём, например, коде.

Присоединяюсь к общему вопросу: авторы, где разбор? А конкретно его часть, относящаяся к задаче E? :-)

Разбор задач Codeforces Beta Round 85 (Div. 2 Only)
  • Проголосовать: нравится
  • 0
  • Проголосовать: не нравится

13 лет назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится
Спасибо за разбор!
13 лет назад, # |
Rev. 2   Проголосовать: нравится 0 Проголосовать: не нравится

По поводу Е.
Можно попробовать устроить мозговой штурм.
Например, у меня есть следующие мысли:
а) почти всегда, ответ обходит все клетки доски или все клетки, кроме одной (от "шахматного цвета" начала и конца)
б) задача, видимо, решается при помощи декомпозиции и разбора случаев.

Действительно, для очень многих случаев работает следующая декомпозиция. Можно разделить начальную и конечную точку горизонтальной (вертикальной) прямой и решить две подзадачи (каждая часть представляет из себя отдельное поле для задачи, а дополнительную пару всегда можно выбрать удачно, если только длина разреза больше некоторой константы).
13 лет назад, # |
Rev. 2   Проголосовать: нравится 0 Проголосовать: не нравится

Все будет, не волнуйтесь :) Просто я сейчас в Петрозаводске и нет времени написать разбор.
13 лет назад, # |
Rev. 3   Проголосовать: нравится 0 Проголосовать: не нравится

Можте объяснить, пожалуйста, поподробнее, что такое "конструктив" и, если есть привести задачу на него? Спасибо.
  • 13 лет назад, # ^ |
    Rev. 2   Проголосовать: нравится 0 Проголосовать: не нравится

    "Конструктив" - придумывание способа получения ответа к задаче как правило нестандартным, работающим только для этой задачи способом. Как правило, решается "на бумаге", поэтому писать много кода не приходится. Что-то типа этого.
    Пример - задачи 98D или 74Е из архива
  • 13 лет назад, # ^ |
    Rev. 2   Проголосовать: нравится 0 Проголосовать: не нравится

    А по поводу задач - можно далеко не идти. Вот вам мегаподборка на нашем уютненьком.

    UPD: Пофиксил ссылку. Не очень понял, почему в неё дописалось /blog/.

13 лет назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится
По поводу С - мой конструктив, например, тест 4 4 проходит. Про остальные два не знаю (лень сейчас проверять). Идея - замостить "пентаминошками в виде звезды" всю плоскость, потыкать один из углов поля в пять клеток различного типа и выбрать минимум. Жаль, что авторы так запутали народ с ограничениями, я думал, что такое красивое построение является верным =)
По поводу схлопывания в троичную маску - очевидно, хранить количество клеток, пауков из которых мы не "пристроили", для каждой строки профиля. Очевидно, что клетки должны идти подряд начиная с края профиля, и их может быть 0, 1 или 2.
  • 13 лет назад, # ^ |
      Проголосовать: нравится 0 Проголосовать: не нравится
    По поводу тестов - вот код Андрея Лопатина. Суди сам, пройдет ли те два теста:

    1. #include <cstdio>

    2. int ans [] = {
    3.   1,1,0,
    4.   2,1,1,
    5.   2,2,2,
    6.   3,1,2,
    7.   3,2,4,
    8.   3,3,6,
    9.   4,1,2,
    10.   4,2,5,
    11.   4,3,8,
    12.   4,4,12,
    13.   5,1,3,
    14.   5,2,7,
    15.   5,3,11,
    16.   5,4,14,
    17.   5,5,18,
    18.   6,1,4,
    19.   6,2,8,
    20.   6,3,13,
    21.   6,4,17,
    22.   6,5,22,
    23.   6,6,26,
    24.   7,1,4,
    25.   7,2,10,
    26.   7,3,15,
    27.   7,4,21,
    28.   7,5,26,
    29.   8,1,5,
    30.   8,2,11,
    31.   8,3,17,
    32.   8,4,24,
    33.   8,5,29,
    34.   9,1,6,
    35.   9,2,13,
    36.   9,3,20,
    37.   9,4,26,
    38.   10,1,6,
    39.   10,2,14,
    40.   10,3,22,
    41.   10,4,30,
    42.   11,1,7,
    43.   11,2,16,
    44.   11,3,24,
    45.   12,1,8,
    46.   12,2,17,
    47.   12,3,26,
    48.   13,1,8,
    49.   13,2,19,
    50.   13,3,29,
    51.   14,1,9,
    52.   14,2,20,
    53.   15,1,10,
    54.   15,2,22,
    55.   16,1,10,
    56.   16,2,23,
    57.   17,1,11,
    58.   17,2,25,
    59.   18,1,12,
    60.   18,2,26,
    61.   19,1,12,
    62.   19,2,28,
    63.   20,1,13,
    64.   20,2,29,
    65.   21,1,14,
    66.   22,1,14,
    67.   23,1,15,
    68.   24,1,16,
    69.   25,1,16,
    70.   26,1,17,
    71.   27,1,18,
    72.   28,1,18,
    73.   29,1,19,
    74.   30,1,20,
    75.   31,1,20,
    76.   32,1,21,
    77.   33,1,22,
    78.   34,1,22,
    79.   35,1,23,
    80.   36,1,24,
    81.   37,1,24,
    82.   38,1,25,
    83.   39,1,26,
    84.   40,1,26
    85. };
    • 13 лет назад, # ^ |
      Rev. 2   Проголосовать: нравится 0 Проголосовать: не нравится

      Спасибо. На обоих тестах закрэшилось =)

      P.S. Не понимаю людей, которые минусуют сообщения, им вроде как вообще не предназначающиеся. Ну если ты больной на всю голову имбецил с кучей комплексов, и тебе даже список ответов к задаче не нравится - ну закрой CF и выстрели себе в висок. Зачем минуса-то на ровном месте ставить? (UPD: это предназначалось какому-то ..., который поставил вам минус до меня)
      • 13 лет назад, # ^ |
          Проголосовать: нравится 0 Проголосовать: не нравится
        Спокойствие, все равно вы никак на ситуацию при текущей системе голосования не повлияете.
        Просто забейте на этих людей, поправьте несправедливо обиженных плюсом. Вклад от этого несильно изменится, заслуженные плюсы найдут своего человека :-)
      • 13 лет назад, # ^ |
          Проголосовать: нравится 0 Проголосовать: не нравится
        Не знаю, у меня, например, вообще написан GreaseMonkey - скрипт для лицемерного голосования. Хотя минус был не мой.
13 лет назад, # |
Rev. 2   Проголосовать: нравится 0 Проголосовать: не нравится

Наверное, не , а . И можно, пожалуйста, пояснение к этой формуле?

  • 13 лет назад, # ^ |
      Проголосовать: нравится 0 Проголосовать: не нравится
    Совершенно верно. Объяснение такое: из количества всех раскрасок вычитаем количества раскрасок, где используется 1, 2, ..., x -1 цветов. 
    Научите, плз, вставлять формулы.
  • 13 лет назад, # ^ |
    Rev. 2   Проголосовать: нравится 0 Проголосовать: не нравится

    Да, конечно. Именно так, как вы сказали. Я поправил, спасибо.

    Почему именно так - всего количество способов покрасить n клеток в x цветов - xn. Из них нам не подходят те способы, где реально участвует некоторые i цветов, где i < x. Количество раскрасок n элементов в фиксированные i цветов, как мы уже посчитали в динамике - D[i]. Соответственно, количество покрасок в какие-то i из наших x цветов - .

    Тем самым и получается общая формула - .

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

      Хм. А у меня все видно. D[x] = xn + ... а не D[x] = nx + ...

      UPD: спасибо. И у меня зашло это решение без всяких оптимизаций за полторы секунды.
      • 13 лет назад, # ^ |
          Проголосовать: нравится 0 Проголосовать: не нравится
        В посте я уже поправил nx на xn. Вы до сих пор видите неправильный вариант?
        • 13 лет назад, # ^ |
            Проголосовать: нравится 0 Проголосовать: не нравится
          Нет, нет, я просто неправильно истолковал сообщение об ошибке трансляции в html. Все ок.
13 лет назад, # |
Rev. 3   Проголосовать: нравится 0 Проголосовать: не нравится

>значит ответ домножается на kn(m - 2).
Наверное все-таки на yn(m-2), или я чего-то не понимаю?
>ответ домножается на вышепосчитанное D[x]2
Не D[x+y]2?