This was a pretty good SRM for me, tantalizingly close to red now. I'll talk about the easy (decent) and medium (really cool), but I didn't have time to take a look at the hard.
Easy (250)
We observe immediately that if n is composite, it takes only 1 move, so all of those cases are done. Then when n is prime, we can just use 1 and n - 1 (which is even), so it takes 2 moves and we're done, right? Almost! For n = 2, the answer is indeed 2 because 1 is not prime, but for n = 3, the answer is 3 because 2 is prime. Those are the only two interesting cases, so now we're really done.
Medium (500)
This is a very nice problem in my opinion because it's not obvious where to start, but once you figure it out it's quite simple. First, let's consider the values in C. If they are all positive or all negative, the answer is - 1. Otherwise, there is a finite sequence because for values + a and - b we can never have a sequence of length ab as it would have to be both positive and negative.
Now, we want to find the longest sequence a1, a2, ..., an satisfying the constraints of the problem. First, we'll note that if N is the maximum value of n that works, then n ≤ N all work and n > N all do not work, so we can binary search on the answer. I don't have a tight bound on the maximum but in the contest I just used 1000000 which is definitely high enough due to the argument above (I'm curious as to a proof of a better one -- it definitely exists because the algorithm does not run in time if the answer is too high).
The way the constraints are specified make them tricky to work with, so instead we'll consider p[i] = a1 + a2 + ... + ai for i = 0, 1, ..., n in which case the constraints can be written as p[i + C[j]] - p[i] > 0 (note this works for both positive and negative C[j]). This induces a directed graph of constraints on n + 1 nodes where an edge from u to v means p[u] < p[v], which reduces the problem to verifying whether this graph of constraints can be satisfied. This is then equivalent to checking for cycles. We can do this in O(n * |C|) time by running a topological sort; alternatively, notice that if there is a cycle then there must be one through 0, so we can just do a BFS from 0. Thus the total running time is O(N * logN * |C|) where N is the maximum possible answer.
Thanks for the post.
About the bound of 2000, you can also find it with sums:
given + a and - b, there can't be sequence of length a + b - 1:
Call s the sum of all the sequences of length a, there are b - 1 of them.
Call t the sum of all the sequences of length b, there are a - 1 of them.
You can check that actually s = t.
Now the constraints imply s > 0 and t < 0, therefore there is no such sequence.
See also this explanation. It looks like the two yellows parallelograms in the third method are related to s = t.
Looking forward to reading a solution on problem 3!! :)
Sure, it only uses up to ~5MB in the worst case, not bad at all.
My code