In this blogpost, we talk about what Challenge problems are and how to solve them. I find them the most attractive questions in a long contest. However, students new to competitive programming often avoid them because they seem weird at first. Lets try and change that.
What are Challenge problems?
A challenge problem in a programming contest uses NP problems to test a candidate. With no perfect answer, the candidate is tested on how good he/she is at finding approximate solutions. This is why the evaluation is score based.
The top scorer is given a score of 100 while the others are given scores as per their closeness to the top score. Usually, problem statements are simple and allow candidates to find interesting nuances while solving. Because of the generality of the problem, a candidate can choose numerous approaches to optimise his/her score. These include Number Theory, Graphs, Data Science, etc…
Some problems require prior knowledge of algorithms, but the best challenge problems are those which have simple explanations and lots of scope for improvement. Such problems allow beginners to try and test their approximate solutions while making sure that the experienced players are tested too.
How do we solve this
MIT professor Patrick Winston makes a brilliant note on problem solving at 42:30 in this video. Here is a summary:
Does the problem reduce to Knapsack? Subset sum? Something else?
Should the main data structure be an array, a list or a tree?
Dynamic Programming? Graph Algorithm? etc…
DFS / Sorting / Edit Distance –> Simulated Annealing / Genetic Algorithm
A key point is that drawing and discussing ideas are far more important than jumping into code. The other super important thing is you can’t follow this process in just one shot. It has to be repeated again and again, with each iteration improving your solution.
First, you need a base solution. Choose a simple, clear cut algorithm(like the first three mentioned below point 4). This is the foundation, setting a minimum guarantee to your score. Invest your time in this, because a weak base solution will directly result in a poor score.
You now need to tweak the best solution you have, updating if you get something better than the current best. Hill climbing, Simulated Annealing or any Evolutionary Algorithm will help you here. Most of the time after this will be spent improving the parameters of the algorithm and improving the time complexity.
Time required to solve them
They can’t be solved in half a day, to be practical. Unless you are looking for an okay score and minimum effort, be prepared to invest significantly.
Also beware of the law of diminishing returns. In general, the more time you invest in these problems, the smaller improvements you will see. The first few hours will give you interesting solutions => perhaps a score of 75 – 85, the next few days might take you to 95-100. And staying there takes tons of effort.
The primary reason why these problems are difficult is because we have to customise and optimise our solutions every time. You can create a general framework for Simulated Annealing to help in the coding phase. However, the ‘representation’ part will change every time.
Upto what point do I keep optimising
Until you feel that there is very little progress being made. To be practical, the other problems will give you many more points for the same amount of effort. When you hit problems beyond your league, come back to improving on the challenge problem solution. Remember that the people at the top have access to the same resources as you do. There is no reason why they should get a better score than you.
When should I start with this problem
This problem will stay at the back of your mind throughout the contest. So it is better to start a little late. More often than not, the problems within our league are solved within the first 80% time of the contest. The challenge problem can be started then.
Final tips and tricks:
- Do not jump into meta-heuristics (Genetic Algorithms, Simulated Annealing) without creating a strong base solution.
- When optimising, try to keep the code clean for later.
- Your nested loops need the most attention, because that where you get maximum gains.
- Greedy is good. Keep your heuristics simple and easy to change.
- If some idea feels too complicated, it is. Save it for the next contest, after reading a little more and being confident about it.
I speak about other topics from competitive programming on my Youtube Channel. You can check them out here.