This post highlights my first experience in solving a “hard” problem on
CodeForces.
I logged in to CodeForces for the first time, I went to the Problemset section
hoping to understand the “competitive coding” ways. I wasn’t sure how the
difficulty rating system worked. Not only that, but I picked the first problem
in the list and tried to have a go.
There are n bags, each bag contains m balls with numbers from 1 to m. For every
i∈ [1, m], there is exactly one ball with number every i in each bag.
You have to take exactly one ball from each bag (all bags are different, so, for
example, taking the ball 1 from the first bag and the ball 2 from the second bag
is not the same as taking the ball 2 from the first bag and the ball 1 from the
second bag). After that, you calculate the number of balls with odd numbers
among the ones you have taken. Let the number of these balls be F , Your task
is to calculate the sum of Fk over all possible ways to take n balls, one
from each bag.
Initial Thoughts
As soon as I saw Fk I thought about
Multi-index n-tuples where
Fk was a tuple of all the odd index selected balls.
But that was stupid, it’s just the regular exponent. Still, it was pretty
interesting of them to ask the sum of the number of balls to the kth
Spoilers
I was definitely stuck on this. There weren’t even any solutions on the internet
either. But I was able to find some similar problems and that’s where
WolframAlpha gave me the key to solve this problem.
Formulating the solution
We can consider the number of was to pick i odd balls from n bags each
containing m balls. This can be found out by:
We basically choose i boxes which we want the odd balls from and each of those
i boxes has m+1/2 choices for odd indices, and then we want to choose even
balls from the n-i remaining bags which have m/2 choices each.
To make the expressions easier to maintain we will
letx=⌊2m+1⌋andy=⌊2m⌋
So the final answer can be formulated as
Ans=i=0∑nik(in)xiyn−i
Where we sum through all the number of odd balls which can be selected (from 0
to n) each contributes ik to the answer.
Now the challenge was the simplify this expression, as it is now it will be way
over the O(n) complexity that is required to solve these “hard” problems.
It seems awfully close to the well known binomial formula but the pesky ik
makes it almost impossible to simplify further.
Luckily after some research on this, I stumbled upon an article on WolframAlpha
about.
Stirling numbers.
They are defined as:
The stirling numbers of the second kind are denoted by the { a b } bracketes
just like the binomial coefficient.
{nk}=n{nk−1}+{n−1k−1}
They also have an interesting property that:
nm=k=0∑m{km}(kn)k!
Which will help us to do something about the the exponent. So without futher
ado,
I present to you, the steps to the simplification:
The first term can be precomputed into a 2-D dp array. The final complexity of
the program should be ∼O(n+c)
Code
This is the final code that I wrote using this approach
Conclusion
I hope you found this thread interesting. I don’t think I will be able to give
much time to the competitive coding side of things. I’d be embarrassed to say the
time it took me to solve this problem, but isn’t it always for the journey? For
me, it’s similar to a Sudoku or a puzzle that I would solve once in a while but
not spend all my brain power on just doing them.