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

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

Сначала в общих чертах о раунде.
Моими задачами в этом раунде были задачи A-div2,  B-div2,  C-div2/A-div1,  E-div2/C-div1,  D-div1. Сначала я хотел провести на них контест исключительно для второго дивизиона. Однако затем мы решили провести общий раунд. MikeMirzayanov подготовил задачу про молоко, anonymous предоставил задачу E-div1. Кроме того, по напутствию RAD были усложнены Аземблер и Флаги.
По-моему, получилось неплохо для первого раза (кроме небольшого фейла с рамочками). Во всяком случае, мне понравилось. Правда, я не ожидал, что Аземблер и Флаги решит так мало народу.

А теперь разбор.


Задача A (div.2) - Восстановление пароля

Текст задачки был актуален чуть более года назад, когда свирепствовал вирус piggy.exe :) Но в то время у меня не было возможности где-либо опубликовать эту задачу.

Пароль восстанавливался достаточно просто. Достаточно перебрать в нем все группы по 10 символов, и, если какая-то группа совпадает с одним из кодов для цифр, вывести эту цифру и перейти к следующей группе.

Вот пример решения: http://pastebin.com/hMV0NcjN

Задача B (div.2) - Друзья

Возможно, некоторых смутила формулировка утверждения. Однако именно так оно звучит в книжке, из которой я его нагло скопировал :)

Построим граф, где вершинами будут люди, а ребрами - отношения между людьми. Обозначим ребра, соответствующие знакомству, красными, а ребра, соответствующие незнакомству - черными. Тогда "трое попарно знакомых" в нашем графе будут представлены циклом длины 3, состоящим только из красных ребер, а "трое попарно незнакомых" - циклом длины 3, состоящим только из черных ребер.

Т.к. вершин в графе всего 5, достаточно написать 3 вложенных цикла for (каждый цикл соответствует одной вершине графа) и проверить, что ребра между этими вершинами имеют одинаковый цвет.

Пример решения: http://pastebin.com/gswaxGmM

На самом деле ответ FAIL будет лишь в одном случае - когда в графе ровно 5 ребер и они образуют цикл длины 5 (как в тесте 2). Вот шуточное решение на эту тему: http://pastebin.com/09T0ixrJ


Задача A (div.1) / C (div.2) - Рамочки

Задача сама по себе довольно простая, но возможностей ошибиться было довольно много, что участники успешно продемонстрировали :) Было решено не устраивать Beta Round 60, а добавить все сложные случаи в претесты.

Итак, давайте разберемся в задаче. Во-первых, заметим, что ответ всегда не превосходит 3, т.к. любое множество подряд идущих папок можно разбить на 3 прямоугольника (возможно, пустых). В первый прямоугольник мы поместим конец первой строки, во второй - все, кроме конца первой строки и начала последней (это будет прямоугольник с шириной m), а в третий - начало последней строки.

Самый простой способ решить задачу --- проверить, что ответ 1 или 2, а иначе вывести 3. Давайте рассмотрим, в каких случаях ответ меньше 3.

Итак, пусть ответ - единица. Значит, все требуемые папки можно выделить за одно движение мышкой. Вот эти случаи (в скобках показан тест для этого случая):

  • первая и последняя папки находятся в одной и той же строчке (21 5 7 9);
  • первая папка находится в самом левом столбце, а последняя - в самом правом (21 5 1 15), этот случай покрывает случай m = 1;
  • первая папка находится в самом левом столбце, а последняя имеет номер n (21 5 6 21). Сюда же относится тот случай, когда надо выделить вообще все папки.

Теперь рассмотрим все случаи, когда ответ равен 2:

  • первая и последняя папки находятся в соседних строчках (21 5 8 14);
  • первая папка находится в самом левом столбце (21 5 6 13);
  • последняя папка находится в самом правом столбце (21 5 4 15);
  • последняя папка имеет номер n (21 5 4 21);
  • столбец, в котором расположена первая папка, находится непосредственно справа от столбца, в котором расположена последняя папка (21 5 3 12). Мне кажется, это самый хитрый случай в задаче.

Если ни одно из этих условий не выполняется, то ответ равен 3.

Пример решения: http://pastebin.com/8QRytzzF

Еще эту задачу можно было писать сжатием координат и перебором, но психов среди нас нет :)


Задача B (div.1) / D (div.2) - Окончание сессии

Задача решается жадным алгоритмом. Нужно последовательно пробовать переливать из каждой бутылки молоко в любую кружку, которая для этого подойдет и в максимально возможном количестве.

В ходе процесса надо помнить, сколько молока находится в каждой кружке и каждой бутылке, а также из каких бутылок наливали в каждую кружку и куда переливали из каждой бутылки. Эта информация нужна, чтобы определять, а можно ли перелить из конкретной бутылки в конкретную кружку или нет.

Остается это просто написать - ничего сложного, как мне кажется. Единственный момент - сравнивать вещественные числа надо, используя EPS. Без этого можно получить WA на тесте 12 (50 1000 49), где из-за неправильного сравнения программы некоторых участников выдавали NO, тогда как решение существует.

В обсуждении ниже показано, что ответ можно считать в целых числах, если взять объем бутылки, равный mn. А при выводе будем делить на mn и умножать на w. Ни одно из трех решений жюри до этого не додумались :)

Пример решения: http://pastebin.com/HG5Nrxne (оно уже не такое красивое, как предыдущие, но понять, как мне кажется, можно)


Задача C (div.1) / E (div.2) - Аземблер

Меня удивило маленькое количество сабмитов по этой задаче. Достаточно маленькие ограничения на n и большое ограничение по времени явно намекали на перебор. Кроме того, интуитивно понятно, что максимальный ответ находится в районе 5.

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

Чтобы при этом не возникло TLE, надо хранить максимальную глубину рекурсии (собственно, это первое число в ответе), в которой мы достигли ответа, и не ходить глубже. Также не следует ходить в те состояния, где мы получаем число, большее n. Если же мы получили ровно число n, и наша глубина рекурсии меньше минимальной, запомним ответ и скопируем его в безопасное место, чтобы потом вывести.

Еще есть улучшение, которое состоит в том, чтобы перебирать числа по убыванию (так работает быстрее), но ограничения в 5 секунд хватало, чтоб перебирать числа как угодно.

Были и другие подходы к решению этой задачи: поиск в ширину и перебор для конкретного ответа.

Вот два решения: обычный перебор (http://pastebin.com/Z6ZF36st) и перебор для конкретного ответа (http://pastebin.com/viiYF9CB).


Задача D (div.1) - Флаги

Сначала я расскажу, как считать ответ для одного числа (т.е. L = R), а потом переделаю решение для общего случая. Дело в том, что изначально задумывалась как раз формулировка с конкретным числом полос N, и только потом мы было принято решение усложнить задачу. Мое решение не сильно оптимально (задачи все-таки не "фиолетовые", как оказалось, а некоторые решения - "фиолетовые" :) ). Я видел коды других участников, и у них все попроще.

Итак, задача для фиксированного N.

Обозначим за число флагов с N полосами, считая симметричные флаги разными. Посмотрим, как, имея эту информацию, получить ответ на задачу.

На первый взгляд, достаточно поделить на 2. Но, посмотрев повнимательнее, можно обнаружить, что это верно только для флагов, не являющихся палиндромами. Например, флаги-непалиндромы WBWB и BWBW симметричны, и надо учитывать только один из них --- здесь деление на 2 законно. А вот флаги-палиндромы, такие, как WBW, симметричны сами себе, поэтому деление на 2 для них приведет к ошибке.

Посмотрим, что можно сделать. Во-первых, заметим, что при четном N корректных флагов-палиндромов вообще не существует, т.к. иначе в центре встретились бы 2 полосы одного цвета, что невозможно, поэтому для четных N формула верна.

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

Итак, мы свели нашу задачу к нахождению числа флагов с N полосами, причем симметричные флаги считаются различными. Заметим, что для того, чтобы пририсовать очередную полосу к флагу так, чтобы он остался корректным, нам необходимо знать лишь последнюю и предпоследнюю его полосы.

Применим динамическое программирование. В качестве состояния возьмем вектор из 8 чисел, каждая компонента которого будет содержать количество флагов c общим количеством полос N и определенными корректными последней и предпоследней полосами (как раз 8 вариантов). Сумма всех компонент этого вектора даст нам общее количество флагов с N полосами, т.е. .

База динамики --- вектор , содержащий ровно 8 единиц (они соответствуют всем разрешенным парам цветов). Давайте подумаем, как можно найти вектор , зная вектор .

Оказывается, существует такая матрица A, что . Элементы этой матрицы можно посчитать даже вручную, из следующих соображений. Например, пусть мы имеем комбинацию последних двух полос WB. Тогда можно справа дописать белую или желтую полосу, что будет соответствовать BW и BY. Поэтому в столбце матрицы, соответствующему WB, мы поставим единички в строках, соответствующих BW и BY. Все это займет не более минуты.

И последний шаг. Очевидно, что . А возведение в степень можно проводить быстро, за логарифмическое время. Принцип в том, что, если N четное, то нам достаточно вычислить и возвести эту матрицу в квадрат. А если N --- нечетное, то N - 1 - четное, и для степени N - 1 можно снова применить этот прием.

Осталось не забыть, что при N = 1 все это неприменимо, зато можно сразу сказать, что ответ равен 4.

А теперь проапгрейдим это решение для случая отрезка .

У меня есть два способа это сделать. Первый способ состоит в том, что в векторе состояний добавляется одна координата, а в матрице - новая строка и столбец. Эта новая координата в векторе состояний будет хранить сумму на отрезке L = 1 разберемся if-ом). Останется подогнать матрицу A, что делается довольно несложно. Попробуйте сами (подсказка: я умножал ее слева еще на одну, почти единичную матрицу).

Второй способ мне понравился больше. Так же, как и ранее, разделим задачу на две: на палиндромы и непалиндромы. Научимся находить ответ для флагов без учета симметрии на отрезке . В вышеприведенных обозначениях ответ равен . Покажем, как можно быстро и просто находить сумму E + A + ... + AN.

Пусть b --- такая максимальная степень двойки, что 2b - 1 ≤ N. Разобьем нашу сумму следующим образом: .

Оказывается, первая часть этого выражения легко считается: . Вы можете сами убедиться в справедливости этого равенства. А сумма в скобках второй части выражения из предыдущего абзаца что-то напоминает... Разберетесь сами :)

Ответ для палиндромов считается таким же способом. Будем полагать для удобства, что L и R - нечетные (если это не так, то к L можно прибавить единицу, а от R - отнять). Тогда .

Вот и все. Остается не ошибиться, после каждой операции брать модуль и внимательно рассматривать крайние случаи.

Вот решение вторым способом: http://pastebin.com/wHu1tPgd

Наверное, можно все сделать куда проще. Пишите свои разборы, чем их больше - тем лучше!



Задача E (div.1) - Лостборн

Эта задача решается формулой включений и исключений. Только многие получили TLE, т.к. они почему-то не прогнали максимальный тест на своем компьютере (да, прогоняйте макс. тесты на своем компьютере!).

А остальные почувствовали, что что-то тут не так, и запоминали ответы для небольших N и конкретного ai в массив, чтобы в дальнейшем их не считать. Например, можно посмотреть решение победителя турнира rng_58, там все очень четко и понятно написано. Вот еще один пример такого решения: http://pastebin.com/4kcfJdAi

Более подробно об этой задаче написал ее автор anonymous вот в этом посте: http://codeforces.com/blog/entry/2216. У него есть решение, укладывающееся в ограничение по времени при N ≤ 1015, что, скорее всего, не сделало бы ни одно из решений, отправленных во время контеста. Это решение можно посмотреть в дорешивании.

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

13 лет назад, # |
Rev. 2   Проголосовать: нравится +4 Проголосовать: не нравится

(исправлено)

13 лет назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится
Меня в задаче C остановило большое количество ребер различных видов и необходимость все это прописывать. Что в общем-то не сильно портит саму задачу.
  • 13 лет назад, # ^ |
      Проголосовать: нравится 0 Проголосовать: не нравится
    А какие там ребра различных видов? На самом деле, только одно - a + kb, все остальное сводится к нему либо установкой a=0, либо k=1. Ну и потом в выводе одно условие добавить. На самом деле, смотрится страшно, но писалась очень быстро - я минут за 20 наклепал, и код получился довольно компактный. Это где-то в 3 раза меньше времени, которое я потратил на задачу A =)))
13 лет назад, # |
  Проголосовать: нравится -9 Проголосовать: не нравится
Спасибо за разбор. Наверно самый подробный из всех на сайте.
13 лет назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится
Ура, все-таки в дорешивании удалось запихнуть обычный перебор в задаче E. Причем сложность выходит не большая, но из-за константы не проходил :(
13 лет назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится
В задаче С див. 1 самый правильный метод, наверное, все-таки был IDDFS, как его обычно называют: сначала перебираем длину ответа от 0 до INF, а потом смотрим, можем ли получить ответ такой длины. Как только нашли - уходим. Тогда рекурсия просто летает. Мое решение, если чуть переписать, будет для нескольких тысяч на работать, а может даже для большей размерности (ушел проверять...)
  • 13 лет назад, # ^ |
    Rev. 2   Проголосовать: нравится 0 Проголосовать: не нравится

    А нельзя было просто дфсбфс по значению двух элементов стека?
    upd. Уже осознал, что я не так понимаю.
    • 13 лет назад, # ^ |
        Проголосовать: нравится 0 Проголосовать: не нравится
      Не очень понял, что понимается под "дфс'ом по значению двух элементов стека". Если, о чем кто-то писал, речь о том, что двух регистров всегда хватает для решения задачи - для меня совсем нетривиально, почему двух хватает, а уж на контесте тем более нетривиально. Если же речь о том, что кидаем в некий стек все полученные значения, а потом на следующем шаге перебираем их все парами - то я так и делал...

      • 13 лет назад, # ^ |
          Проголосовать: нравится 0 Проголосовать: не нравится
        Имелось в виду не дфс, а бфс (опечатка была). Ну в общем, да, я вас сначала неправильно понял, я подумал, что вы делаете, как я, только почему-то перебором.
        • 13 лет назад, # ^ |
            Проголосовать: нравится 0 Проголосовать: не нравится
          Кажется, я тоже понял вашу идею с бфс'ом, но я не понимаю, зачем бфс'ить. Сложность по времени получается та же, а по памяти - гораздо больше (нужно довольно много вариантов хранить), а я их генерю на лету. Поэтому и по времени это может работать дольше. Ну и, кроме того, пишется перебор все-таки быстрее.
          • 13 лет назад, # ^ |
              Проголосовать: нравится 0 Проголосовать: не нравится
            Странно беспокоиться о 256^2 ячеек памяти. А почему сложность у перебора такая-же - не очень понятно.
  • 13 лет назад, # ^ |
    Rev. 2   Проголосовать: нравится 0 Проголосовать: не нравится
     
13 лет назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится

Не знаю, писали ли это где-то раньше и вообще работает ли, но. Когда я писал, мне в голову приходила мысль типа следующей. Очевидно, емкость бутылки - величина не очень важная и решение для одной величины легко переделать в решение для другой простым домножением. Тогда, если емкость бутылки взять равной числу участников, то задачу можно будет решать целочисленно, т.к. каждый участник будет хотеть целое число молока (равное числу бутылок).


13 лет назад, # |
  Проголосовать: нравится +22 Проголосовать: не нравится
Почему-то автор разбора не написал про задачу B (див. 1) главное - почему это работает. Кто-нибудь может объяснить?
  • 13 лет назад, # ^ |
      Проголосовать: нравится +3 Проголосовать: не нравится

    Поддерживаю!

    Именно это больше всего интересовало в разборе.

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


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

    Вот мой вариант доказательства (не гарантирую, что оно на 100 процентов правильное). Мы имеем дело с двумя случаями:
    1. n >= m. Тут очевидно мы сможем заполнять кружки бутылками подряд, так как либо бутылка полностью помещается в кружку, либо если это не так, то ее остаток полностью поместится в следующую.
    2. n < m. Тут одна бутылка в одну кружку никак не поместится целиком. Если 2n < m - сразу NO. Иначе сначала докажем, что оптиматьно заполнить хотя бы одну кружку полностью молоком из одной бутылки, а далее аналогично докажем для m-1 кружек, что есть смысл заполнять их подряд (точно так же, просто с учетом того, что одна из них уже не пуста). Доказательство сложно привести без иллюстраций, суть его в методе от противного и в том, что в итоге мы либо заполним какую-то кружку только одним молоком, либо переполнимася на 3 кружки. Ну и не забыть про тот факт, что n < m.
    • 13 лет назад, # ^ |
        Проголосовать: нравится +5 Проголосовать: не нравится
      По-сути, доказательство Вы не провели. Разобранные случаи и так тривиальны. Интересует как раз случай n < m < 2n. И не очень понятно, как делать "далее аналогично докажем для m-1 кружек" - аналогии нет, поскольку раньше все бутылки были полный, а теперь - одна частично пустая.
      • 13 лет назад, # ^ |
        Rev. 3   Проголосовать: нравится 0 Проголосовать: не нравится

        Вы не до конца разобрались или я криво написал. Доказав, что одну кружку нужно полностью заполнить из одной бутылки, а ее остаток полностью вылить в другую, можно доказать и то же самое для n-1 бутылок и m-1 кружек, одна из которых (кружка) уменьшилась в размерах.
        UPD Доказательство действительно не верное, см корректное ниже
13 лет назад, # |
Rev. 4   Проголосовать: нравится +13 Проголосовать: не нравится

Набросок доказательства B div 1.

Пусть n < m, т.е. кружка меньше бутылки. Пусть кружки - вершины графа. Пусть каждая бутылка задает ребро графа (соединяет две кружки в которые из нее налито). Пусть на ребре, входящем в вершину, подписано, сколько в эту вершину наливается из соответствующей ребру бутылки, а текущий граф задает ответ задачи.

Пусть в этом графе есть некоторый цикл. Тогда k кружек получают все содержимое k бутылок, что невозможно.

Введем операцию проталкивания объема d по некоторому пути. Она будет заключаться в уменьшении для каждой бутылки на пути количества наливаемого на d в вершину, которая на пути раньше, и увеличения на d в вершину, которая позже. Это приводит к недоливу в первой вершине пути и переполнению в последней, причем можно выполнять эту операцию на объем вплоть до того, когда последняя бутылка пути будет полностью выливаться в последнюю вершину пути (внутри пути такого произойти не может, так как это автоматически означает переполнение вершины).

Пусть теперь у нас есть некоторый путь A->B. Протолкаем максимально возможное значение по этому пути. Получится, что в вершине А недолив, в В перелив, последняя бутылка пути целиком выливается в В. Перельем нужное количество молока из последней бутылки пути в А. Таким образом, для любого пути V1 -> V2 -> ... -> Vk мы можем убрать ребро Vk-1 -> Vk и добавить ребро Vk -> V1.

Этой операции достаточно, чтобы любой лес превратить в лес со степенью каждой вершины не больше 2, т.е. свести любой ответ к ответу, в котором наливание идет жадным способом.

Предложения по тому, как написать это яснее, принимаются.

  • 13 лет назад, # ^ |
      Проголосовать: нравится 0 Проголосовать: не нравится
    У вас опечятка: B div 1,  а не C
  • 13 лет назад, # ^ |
      Проголосовать: нравится +5 Проголосовать: не нравится
    1. Граф ориентированный или нет?
    2. Пусть каждая бутылка задает ребро графа (соединяет две кружки в которые из нее налито). Пусть на ребре, входящем в вершину, подписано, сколько в эту вершину наливается из кружки, а текущий граф задает ответ задачи.
    То есть я правильно понимаю, что на каждом ребре будет написано два числа? И из какой кружки наливается в вершину?
    • 13 лет назад, # ^ |
        Проголосовать: нравится 0 Проголосовать: не нравится
      1. Граф не ориентирован.
      2. На каждом ребре подписано два числа, сумма их равна объему бутылки.
    • 13 лет назад, # ^ |
        Проголосовать: нравится 0 Проголосовать: не нравится
      ой, там еще одна жесткая описка. Кружка - вершина, Бутылка - ребро. Наливать можно только из бутылки.
      • 13 лет назад, # ^ |
          Проголосовать: нравится 0 Проголосовать: не нравится
        Сейчас мне нравится все, кроме одного: почему при максимально возможном проталкивании разрыв будет именно на последнем ребре, а не где-либо по пути?
        • 13 лет назад, # ^ |
            Проголосовать: нравится 0 Проголосовать: не нравится
          Пусть разрыв будет посередине, т.е. мы не можем протолкать больше, чем уже протолкали сейчас.
          Это означает, что некоторая бутылка пути полностью выливается в некоторую вершину, что автоматически означает переполнение этой вершины и тот факт, что эта вершина - последняя (проталкивание вызывает переполнение только одной вершины).

          На самом деле, вдоль любого пути количество налитого из бутылки в более позднюю вершину пути убывает, это следует из утверждения "кружка меньше бутылки" и того факта, что все, что не налили в следующую вершину, наливается в эту.
  • 13 лет назад, # ^ |
      Проголосовать: нравится 0 Проголосовать: не нравится

    Упростил, как мне кажется, доказательство, используя Вашу идею с графом. Очевидно что граф ацикличный, то есть разбит на деревья, в каждом дереве число ребер равно числу вершин минус 1, а количество деревьев равно k=m-n. Тогда составим уравнение для произвольной компоненты связности с числом вершин m0 и числом ребер n0: m0*w*n/m=(m0-1)*w. m0=n0+1, отсюда m0=m/k, а n0 = n/k, причем все компоненты одинаковы, значит нужно решить задачу хотя бы для одной. Заметим, что если мы не можем получить целочисленные m0 и n0, то задача решения не имеет. В противном случае задача для количества бутылок n0, которое на 1 меньше количества кружек m0 решается всегда очевидным образом (применить решение в целых числах).

    • 13 лет назад, # ^ |
        Проголосовать: нравится 0 Проголосовать: не нравится
      Да, наверное, я не заметил очевидного по дороге.
      При n >= m решение существует всегда
      При n < m решение существует т. и т. т., когда n / gcd(m,n) + 1 == m / gcd(m,n)
13 лет назад, # |
  Проголосовать: нравится +8 Проголосовать: не нравится
Задача D гораздо проще решается
Пусть fn - 1, 2, 3, 6, 9, 18, 27 и т.д. (чередующиеся степени тройки и удвоенные степени тройки. Тогда ответ без выкидывания симметричных - 2fn + 4fn - 1. Для учета симметрий заметим, что симметричных ответов для четной длины нету, а для 2n - 1 их ровно как любых ответов для n. Таким образом нам надо посчитать несколько сумм геометрических прогрессий
  • 13 лет назад, # ^ |
      Проголосовать: нравится 0 Проголосовать: не нравится
    Так и знал, что формула там выводится нормальная :)

    Не читал разбор, посмотрел, что он очень длинный. Кажется, что для задачи, в которой надо посчитать какие-то матричные возведения в степень с какими-то уточнениями в разборе и правда много букав.
    • 13 лет назад, # ^ |
        Проголосовать: нравится 0 Проголосовать: не нравится
      Там ровно один экран, если начинать с места, где говорится о возведении матрицы в степень. А раньше идут всякие очевидные объяснения.
  • 13 лет назад, # ^ |
      Проголосовать: нравится 0 Проголосовать: не нравится
    Проще, конечно, если заметить эту закономерность.
    На контесте почти все возводили матрицы в степень.
    • 13 лет назад, # ^ |
        Проголосовать: нравится 0 Проголосовать: не нравится
      А вот я когда понял что у меня Е тлится быстренько нашел эту закономерность и долго тупил почему задачу никто не сдает :)
13 лет назад, # |
  Проголосовать: нравится +4 Проголосовать: не нравится
My "compact" div2 - A : http://pastebin.com/inZP2qfg
13 лет назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится
Can I know if there is a proof that the greedy solution for Div1 - B works? I can only prove that if n >= m this works, and if 1.5n < m it always does not work.
  • 13 лет назад, # ^ |
    Rev. 4   Проголосовать: нравится 0 Проголосовать: не нравится

    If n<m, it works if and only if n % (m-n) = 0 and 2n<=m. w is meaningless, therefore let w=1. It's easy to observe that after using each bottle, one more cup is full and the volume of milk in last cup (call it v) increase by a constant. For ex,  n=3 m=4 (here constant is 1/4)
    At the beginning, v=0.
    Bottle 1: v=0. Pour 3/4 into cup 1 and 1/4 into cup 2. 
    Bottle 2: v=1/4. Pour 2/4 into cup 2 and 2/4 into cup 3.
    Bottle 3: v=2/4. Pour 1/4 into cup 3 and 3/4 (= 0) into cup 4.
    It's similar if we pour 3/4 of 3 bottles into 3 cups and the rest 1/4 of 3 bottles into the other.
    So, divide it into 2 progresses.
    1. Make n cups full with n bottles. Each bottle remains the same volume of milk.
    2. Make the other m-n cups full. So n%(m-n)=0 is the condition.
    • 13 лет назад, # ^ |
        Проголосовать: нравится 0 Проголосовать: не нравится

      Here is another proof for the greedy algorithm:

      Let's forget w, and declare that each bottle contains m/n cups.
      If n<m, then each bottle must be poured in two cups.

      Consider the following graph:
      Nodes are cups, and two cups are connected if they are filled using a common bottle.
      The graph has m nodes, n edges.  Consider a connected component, c its number of nodes.  c cups need c*n/m bottles to be filled.  On one hand, c*n/m<c, and on the other hand, there are at least c-1 edges.  In the end, each connected component must be a simple path.  Pouring in the order of each simple path is exactly the greedy algorithm.
13 лет назад, # |
  Проголосовать: нравится +10 Проголосовать: не нравится
I think there has some presentation error in solution D(div1)

Author said:
If N is odd, the correct formula is , where is the number of palindromes with N stripes. Each palindrome is definited by its first stripes, and we can write that .
which means ans(N) = f(N) / 2 + f((N + 1) / 2) when N is odd.

but actually, ans(N) = (f(N) + f((N + 1) / 2) / 2

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

Fixed, thank you
»
5 лет назад, # |
  Проголосовать: нравится -6 Проголосовать: не нравится

DIV-1 (A)

in the first sample you can select the folders with 2 frames

you need to select folders (3,4)

then you can select folders from 5 to 9....

i saw the tutorial for this problem and i saw:

"and another tricky case: if the column where first folder is located is just at right from the column where the last column is located (21 5 3 12)"

i think this case could explain my solution for the first sample...