441A - Валера и антиквариат
Автор задачи gridnevvvit
Нужно реализовать то, что записано в условии. Например, это можно сделать так: посчитаем qi — минимальная цена товара у продавца i Тогда если qi < v, то мы можем заключить сделку с продавцом i. Иначе не сможем.
Авторское решение: 6850474
441B - Валера и фрукты
Автор задачи gridnevvvit
Будем последовательно перебирать дни от 1 до 3001. Пусть текущий день это день i. Кроме того, дополнительно будем поддерживать величину cur --- количество фруктов, которые мы не успели собрать в предыдущие дни. Предположим, что в день и созреет now фруктов. Если now + cur ≤ v, то нужно добавить к ответу now + cur и обновить значение cur (cur = 0). Иначе к ответу нужно прибавить величину v, а величину cur обновить следующим образом. Пусть tv = max(v - cur, 0). Тогда cur будет равен величине cur = now - tv. Иначе говоря, сначала мы пытаемся собрать те фрукты, которые завтра уже испортятся.
Кроме того, можно решить задачу и за . Однако, этого не требовалось.
Авторское решение: 6850502
Бонус. Предположим, что фрукты можно собирать в дни ai, ai + 1, ..., ai + Ti, где Ti — некоторое заданное число для каждого дерева. Как решить оптимально такую задачу? Да, еще. Кроме того, для каждого дня заданное свое значение v (производительность труда в каждый день).
441C - Валера и трубы
Автор задачи gridnevvvit
Задача решается довольно просто. Сначала построим такой обход прямоугольной таблицы, который посещает все его клетки. Его построить очень просто:
- Пусть сначала мы стоим клетке (1, 1). Слева направо дойдем до самой правой клетки поля в этой строке, до клетки (1, m).
- Перейдем на следующую строку, в ячейку (2, m). Справа налево дойдем до самой левой клетки поля в этой строке, до клетки (2, 1).
- Перейдем на следующую строку. Повторим действия из пунктов 1. и 2. до тех пор, пока не посетим все клетки.
После того, как мы построили такой обход, получить ответ не трудно: достаточно первые (k - 1) трубу сформировать из 2 ячеек, а последнюю трубу из оставшихся.
Авторское решение: 6850508
441D - Валера и обмены
Aвтор задачи danilka.pro
В данной задаче удобно представить перестановку в виде ориентированного графа c n вершинами, а из каждой вершины i проведено единственное ребро в вершину p[i]. Очевидно, что этот граф полностью состоит из простых циклов.
Если провести операцию обмена (i, j), то ребра и станут ребрами и соответственно. Тогда, если i и j находятся в одном цикле, то этот цикл разорвется:
а если в разных, то циклы, в которых они содержатся, соединятся в один:
а это значит, что любая операция обмена либо увеличивает число циклов на один, либо уменьшает на один.
На основании всего вышеизложенного, чтобы получить перестановку q из перестановки p, нужно увеличить (или уменьшить) число циклов в перестановке p до n - m. Пусть с — число циклов в перестановке p. Тогда k всегда равно |(n - m) - c|.
Для выполнения условия лексикографической минимальности, рассмотрим три случая:
1) n - m < c
Очевидно, что в этом случае выгоднее всего уменьшать число циклов, соединяя их с циклом, содержащим вершину 1. Таким образом, в этом случае любой обмен имеет вид (1, v), где v > 1. Поскольку вершина каждого последующего цикла больше предыдущей, данный случай решается за O(n).
2) n - m > c
В этом случае необходимо для каждой вершины разрывать ее цикл, совершая обмен с наименьшей возможной вершиной (она так же должна находится в цикле). Это можно сделать, если представить цикл в виде строки . Поскольку каждый цикл разрывается за линейную сложность, такое решение работает за O(n2).
Бонус: данный способ представления цикла позволяет оптимизировать решение до ассимптотики , можете подумать, как.
3) n - m = с
Так как в этом случае k = 0, никаких обменов делать не нужно.
Крайне рекомендуется ознакомиться с авторским решением: 6850515
441E - Валера и число
Автор задачи gridnevvvit
Решать задачу будем следующим образом: будем считать динамическое программирование d[i][mask][last][cnt] — вероятность получить через i шагов такое число v, что его последние 8 бит равны маске mask, 9-ый бит равен значению last, а cnt — это количество подряд идущих бит (начиная с 9-го бита) которые равны по величине значению last.
Хорошо, а почему мы отбросили остальные биты? Понятно, что используя операцию + = 1 мы сможем изменить только первый нулевой бит, индекс которого ≥ 9.
Переходы достаточно очевидны: либо мы прибавим единицу, либо * = 2 (Подробнее их можно изучить в моем решении). Возможно, следует задать вопрос такой. Например, мы имеем число в двоичном представлении x = 1011111111.
И в текущий момент, мы делаем + = 1. Согласно тому, что я написал выше, мы должны перейти в состояние d[1][0][1][2], однако мы не сможем этого сделать, поскольку у нас нет никакой информации о 1 в 10-ой позиции. Однако, поскольку мы не сможем больше изменить никакой бит с индексом > = 9 (так как mask = 0) мы сделаем переход в состояние d[1][0][1][1].
Авторское решение: 6850523
Бонус. Предположим, что мы имеем немного другой псевдокод.
// input x, k, p
for(i = 0; i < k; i += 1) {
if (x четное) {
rnd = случайное число на отрезке [1, 100]
if (rnd <= p)
x *= 2;
else
x += 1;
} else {
x *= 2;
}
}
s = 0;
while (x четное) {
x /= 2;
s += 1;
}
Как и прежде, нужно найти математическое ожидание s.
Насколько эффективно вы можете решать такую задачу? Можете ли вы доказать свое решение?
Бонус задачи B
Заведем массив векторов из пар для каждого дня, в каждой паре будем хранить приоритет и номер дерева с которого можно срывать в этот день. Затем сортим по приоритетам и проходясь по дням считаем ответ. Пусть худший приоритет будет Xi, где Xi — количество дней в которые можно срывать. Тогда приоритет, требующий обслуживания прямо сейчас равен 0.
UPD Точно так же можно было решать и саму задачу B, только в ней было два приоритета — 1 и 0.
Умею решать бонус к задаче Е за .
Заметим, что s = numberOfTrailingZeros(x).
На каждой итерации будем хранить вектор вероятностей v = (v0, v1, ...)T, где vi = prob[numberOfTrailingZeros(x) = i]. Изначально vn = 1 и vi = 0 ∀ i ≠ n, где n = numberOfTrailingZeros(x).
Теперь заметим, что если у нас на какой-нибудь итерации x нечетное, то перейти можем только в состояние с одним не ведущим нулем, в противном случае, пусть m = numberOfTrailingZeros(x), тогда переходы возможны в состояние с нечетным числом с вероятностью и в сосстояние с m + 1 не ведущим нулем с вероятностью . Дальше несложно построить матрицу переходов:
Осталось только возвести M в k-ую степень, домножить на v и посчитать матожидание.
я умею решать гораздо быстрее.
Ну да, матрица лишняя.
dp[номер текущей итерации][количество не ведущих нулей в бинарном представлении] — состояний, переходы за описаны выше. Итого .
Но можно ещё быстрее!
Будем хранить дерево отрезков, которое умеет считать сумму на отрезке, изменять в точке и домнажать числа на отрезке на константу. Пусть m — позиция, начиная с которой в дереве отрезков хранится наша динамика (изначально m = k). Тогда все наши действия эквивалентны следующему коду (код понять легче, чем объяснить словами):
То есть мы на каждой итерации наша динамика хранится в отрезке [m, m + size].
Итоговая сложность .
На самом деле, это не предел. Рассмотрим отдельно два случая, когда p = 0 и когда p = 100. Это достаточно просто, я не буду описывать как это сделать.
Теперь пусть 0 < p < 100 и pl = (100 - p) / 100. Рассмотрим вероятность нулевого количества бит на i шаге. Пусть эта величина равна x. Тогда на следующем шаге вероятность нуля будет равна f(x) = (1 - x) * pl. Хорошо. Давайте найдем производную (f'(x)) такой функции. Очевидно, она равна f'(x) = - pl. Значит, для любого x |f'(x)| < 1, значит f(x) сжимающее отображение (понятие из функционального анализа). У сжимающего отображения есть одна неподвижная точка, к которой будет сходится последовательность x, f(x), f(f(x)) и так далее. А поскольку при больших k вероятности получить больше нулей на конце в двоичной записи зависят как раз от вероятности нуля, то искомый ряд вероятностей сойдется к некоторому ряду. На практике же, можно ограничится тем, что k можно ограничить небольшим числом, например значением 1000 (вроде это уже даже многовато).
When will the eng for div2 d, e come out?
When will english translations be available?
I think the google translation is not — so — bad, so you can try it out!
Now.
In problem E editorial, what is 'v' (mentioned in first line)? I would also like to know how you arrived at the DP state you described. Thanks!
v — is some number, which satisfy this pattern (mask, last, cnt).
Because number of operation is small ( ≤ 200) then we can understand, that only last 8 can be changed by adding operations (and first zero bit with index ≥ 9). So, after that we will have such dp states
Can you please give example of how the states are represented by dp[i][mask][last][cnt]?
Sorry,I just press the wrong button.I just want to ask,as there are so many states,will it TLE?Is the transfrom O(1)?
How an easy solution for C!!! I wrote a complex code to do this task, and finally it was failed on system test :(
It's not the first time for me doing this mistake, any suggestion? any trick? How can I think about problems in the easier manner?
Sorry, but I don't understand well dans' explanation about problem D, why always do we need to increase (or decrease) number of cycles in p to n - m?....... What about if we have only a cycle with length m + 1, could be that q? can anyone explain that?
Because to break a cycle into 1-length cycles with length l you need l - 1 swaps. Then to break all the cycles you need swaps. c is number of cycles in p.
Problem D-
how output of
3
2 3 1
0
is
2
1 2 1 3
this will happen with above ans (231) -> (132) -> (312) but final state should be (123)
EDIT: I got it. swap is operated on index. my mistake.
I am unable to understand how the graph is used for representing the permutation,can anyone help me??If there exist a only 1 edge from i to p[i], then how cycles are formed??
This image shows graph representation of permutation 3 4 5 2 1.
okay got it,thanks
can aNybody plz explAin problem E, this type of problem is completely new for me or link to some tutorial?
Problem E could be solved using dynamic programming method. It is very common, so the better way is to inspect others solutions. Even this task could be solved using DP in different ways. If you are completely new to DP, you can read Wikipedia, inspect posts on Codeforces, or simply use google for it.
Hi guys,
I've seen others' dp solutions such as 6963686 that have used way easier dp solutions than the one in the analysis (this solution uses only 2 dimensions for the dp). Does anyone know an explanation to their solutions? I've read them really throughly and don't quite understand them. Thanks everyone for their help!
dp[i][j]
— answer for x + j if we have i operations left.Только что решил задачу D при условии, что обменивать можно только соседние ячейки. Глупо было пропустить этот момент в условии, но модифицированная задачка тоже получилась довольно интересной. Рекомендую.
Im sorry i can't understand what variable m stands for,
can someone please explain it to me ??
Seems, that in problem C and problem D m is variable from the input.
There is a similar problem to problem D
"Silly Sort" SPOJ SSORT / 2481 Live Archive / 2002 World Finals ACM
I solved it with the same idea for problem D. The property of that every swap increase or decrease the number of cycles in a permutation(see graph in tutorial) is very useful.
Links:
SSORT
Well, these problems are not similar. They use similar idea, but greedy algorithms are different.
I don't refer for greedy algorithm , in fact i explain in my comment about idea of (that every swap increase or decrease the number of cycles in the graph by one)
This is the similar.
I think this is really a great contest especially the problem D and E.I have never seen these problems and I have learnt a lot from these problems.
The case 2 of 441D - Valera and Swaps can be solved in O(N) using stack
Note that the numbers you choose to swap with the same i are always increasing
We can interate through p[i] → p[p[i]] → ... with a stack to maintain a lexicographical-smallest increasing sub-ring
When you pop some elements, you remove a monotonic sub-ring from the current ring, and thus the order to swap for the sub-ring is certian
Just store them, you dont have to recaculate them
Total time complexity: O(N)
See my code 22617043 for details
Amazing!!! XD
We can do div2 B in O(n) too!! Solution: 6850502
We can do div2 problem B in O(n) too!! solution: 65319642
Why problem D has tag "string suffix structures"?
i am getting wrong output format Unexpected end of file — int32 expected for problem c https://mirror.codeforces.com/contest/441/submission/263797142
dis it happen with anyone else