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

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

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

Сегодня в час ночи по Москве состоится третий раунд Facebook Hacker Cup. Топ-25 кулхацкеров выходят в финал.

Ссылка на вход для участников и наблюдателей.

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

»
12 лет назад, скрыть # |
 
Проголосовать: нравится -6 Проголосовать: не нравится

Ну вообще ад :) Как что решалось?)

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

    Ну в первой у меня формула включения-исключения

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

      Типа как для подсчета беспорядков?

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

      И как она помогает?

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

        Ну типа f(i) — количество способов подарить подарки так, чтобы не менее i получили подарки из своей же семьи. Считается f(i) так: динамика DP(семья, позиция текущего чувака в семье, сколько подарков в семье мы распределили уже, сколько из i осталось распределить). Так f(i) = DP(0, 0, n[0], i)·(N - i)!, где N — сколько всего чуваков.

        По этому штуке запускаем формулу включения-исключения и voilà!

        Кстати, решение за O(N2·max(ni)), то есть в данном случае за квадрат, без ограничений на ni — за куб.

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

    20 — будем строить какой-то цикл, начиная из произвольной группы. Это делается динамикой по количеству оставшихся групп каждого размера, а также размерам групп, которые содержат начало и текущий конец цепочки. Аккуратно считаем, не проводя ребер из группы в себя же.

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

    У меня пятимерная динамика. Добавляем чуваков по одному. Добавили уже i чуваков. Пусть D[i][k][a][b][c] — количество способов дойти до состояния, когда у нас:

    • k корректных цепочек, начинающихся на чувака не нашего цвета и кончающихся на чувака не нашего цвета
    • a корректных цепочек, начинающихся на чувака нашего цвета и кончающихся на чувака не нашего цвета
    • b — то же самое, только наоборот
    • c — количество цепочек, начинающихся и кончающихся на чуваков нашего цвета.

    А дальше смотрим, куда мы можем подцепить очередного и пишем десять, блин, переходов. Я час не мог поверить, что все писали это за десять минут =(

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

    Интересно видеть такой вопрос от человека, который послал все задачи...

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

    У меня на 20 ДП, a[i][j][k] — кол-во способов обработать i семей, при этом j людей из первых i семей ещё не дарили подарка и k людей из первых i семей ещё не получали подарки. Переход вполне простой, и думаю что это можно написать быстро, если не тупить как я. :D

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

Man, that was... definitely harder problems than last year. No AC on the 2nd problem...

I solved the 1st problem with O(K2C) dynamic programming, taking (number of processed families, number of gifts added between them) as a state; C is some large constant here, if we consider the size of a family to be constant — and small.

I realize that if the 2nd problem looks really easy, costs that many points, and is in the last round, it will be something really hardcore, so I never even tried to code anything on it :D

I spent most of the time on the 3rd problem, and managed to prove that the graph must be bipartite, planar (there's no solution for K3, 3) and got to the assumption that is must be reducible to a single edge by the operation "find 2 connected vertices of degree 2 and delete them". Is it good or completely off-topic? :D

Still, top 50 is good enough...

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

    How have you proven that graph must be planar?

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

      I proved that satisfying the main condition for K3, 3 (as a subgraph) leads to a contradiction.

      I'll assume you know the trivial rules for vertices at distance 1.

      Firstly, a lemma about K2, 2: let's say that one partition of a subgraph K2, 2 contains vertices (1,2) and the other (3,4); w.l.o.g., associate vertex 1 with a subset S1 of chains, such that no other vertex is associated with a smaller set. Then, for vertices 3 and 4, we have S3 = S1 + a and S4 = S1 + b (a, b are also chains, and a ≠ b), and then S2 = S1 + a + b, because if S2 didn't contain (w.l.o.g.) a, then S2 = S1, which is impossible.

      I just realized there's a stroger version, working on any subgraph K2, 3. Let's use the same notation as above (partitions (1,2) and (3,4,5)); S3 = S1 + a, S4 = S1 + b, S5 = S1 + c. There are 2 possible cases: |S1| is the smallest or |S3| is the smallest (w.l.o.g.). If it's S1, then by the lemma on K2, 2 (1,2,3,4) and (1,2,3,5), we have S2 = S1 + a + b = S1 + a + c; otherwise, by the lemma on (1,2,3,4) and (1,2,3,5), we have S4 = S3 + a + b = S5; both are contradictions. QED.

      My mistake, it doesn't imply planarity. K3, 3 can be a subgraph of a minor, it just can't be a direct subgraph.

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

    The fact the graph should be planar isn't true. 5-dimensional binary cube (vertices are numbers from 0 to 31, edges between pair of integers if they differ in exactly one bit) isn't planar, but is easily colorable.

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

      Yeah, my mistake. I just confused the rules of planarity a bit. Still, the planarity was just a peculiar note, not anything important :D, what I was proving back then was non-existence of K3, 3.

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

    Could you elaborate on the first problem. I don't see how your state in dynamic programming is sufficient. My understanding is that it's also important how the other gifts (those that were not added between the processed families) are distributed.

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

      Yes, it is important. It's all hidden in the large constant.

      Let's say that we're processing family i, and there are j people so far that haven't given/received (those 2 numbers are equal) any gifts. Out of ni people of this family, x can give gifts to processed people, and y can get gifts from the processed people, moving to a state (i, j + ni - x - y).

      Now, combinatorics ensues. Let's assume that the conditions of at least 1 way existing (x, y ≤ j, ni etc.) are satisfied. There are ways to choose the x people, ways to choose y and those 2 groups are independent. There are j(j - 1)..(j - x + 1) ways to choose which people of the j will get gifts from our x, and j(j - 1)..(j - y + 1) ways to choose the same for those giving gifts to the y. Those are just small products and can be enumerated with modular arithmetic in O(ni) = O(1) time.

      So even if there are many ways, those are compressed to the combination-variation product; in the dp state, they're viewed as equivalent and they're differentiated only when picking some few of them.

»
12 лет назад, скрыть # |
 
Проголосовать: нравится +33 Проголосовать: не нравится

Расскажу, как я решал третью задачу.

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

Сопоставим каждому ребру номер ресторана, в котором отличаются соединённые им города (будем называть это цветом ребра). Заметим, что цвета рёбер — это всё, что нам нужно: если инвертировать наличие ресторана для всех городов, ничего не изменится. Оказывается, раскрасить рёбра, соблюдая условия задачи, можно не более чем одним способом (с точностью до перестановки цветов). Ответ — число различных цветов.

Пусть мы выбрали ребро AB и хотим найти все рёбра такого же цвета. Будем считать, что в A соответствующего ресторана нет, а в B есть. Рассмотрим на некоторую вершину C. Расстояние от C до A и B будет отличаться на 1 (иначе граф не двудольный). Утверждается, что если C ближе к A, то там этого ресторана нет, а если к B, то есть. Соответственно, если ребро соединяет вершину, которая ближе к A, и вершину, которая ближе к B, то оно того же цвета, иначе нет. Это определяется с помощью BFS из двух вершин.

Так раскрашиваются все рёбра. Если уже проверено, что граф двудольный, и при раскраске ни разу не приходилось красить одно и то же ребро два раза, то можно доказать, что на каждом цикле каждый цвет будет встречаться чётное число раз. Значит, множество цветов, встречающихся на пути из одной вершины в другую нечётное число раз, не зависит от пути. Осталось проверить, что для каждой пары вершин размер этого множества совпадает с расстоянием между ними. Для этого из каждой вершины с помощью BFS считается расстояние, затем DFS с отслеживанием множества (и его размера) всё проверяет.

Итоговая сложность O(nm), у меня работало 50 секунд.

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

.

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

Funny that C appeared on team competition in Poland 2 weeks ago :P (problem M here http://www.mwpz.poznan.pl/zadania.php). In slightly different version, but main idea was exactly the same. Nobody solved it during the contest, but few guys successfully googled it :P.

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

Here's a solution to Pizza Baking (the second problem).

Let S_i be the total number of pizzas that need to be in an oven at time i. Then the key lemma to this problem is that the number of ovens needed to satisfy the requirements is always max(ceil(S_i / C_i)). While it's an obvious lower bound I still don't have a clean proof of its correctness.

Given this lemma, we first calculate the number of required ovens, call it M. Then we'll add a virtual pizza at every time so that S_i = C_i * M at all times. Therefore it will be necessary to fill every oven to maximum capacity at all times.

We can find such an assignment that fills the oven to capacity using max flow. To do so we will have K + 1 nodes for each time. Then for each pizza we'll connect its start time to its end time (where the times are in [s, e) form instead of the [s, e] form given in input). Now imagine that there are capacities from the source to the time nodes and from the time nodes to the sink node. Then we can compute the number of pizzas selected by the flow at time i as sum[j<=i] flow[source][j] — flow[j][sink]! Therefore we just need to setup the capacities from the source and sink nodes to time nodes so that in a maximal flow the oven is at capacity at all times.

Therefore we should set cap[source][i] = max(0, C[i] — C[i — 1]) and cap[i][sink] = max(0, C[i — 1] — C[i]).

Now we use this flow concept and try forcing pizzas to be used and verifying that a feasible solution still exists. If we reuse old flow networks this can lead to a rather efficient solution.

Code: https://gist.github.com/msg555/8078816

»
12 лет назад, скрыть # |
 
Проголосовать: нравится +5 Проголосовать: не нравится

T-Shirts are coming! Got mine today.

»
12 лет назад, скрыть # |
 
Проголосовать: нравится +5 Проголосовать: не нравится

Anybody knows, it is OK that i have not received my t-shirt yet?