The course will cover many different topics. We will start out by studying various combinatorial algorithms together with techniques for analyzing their performance. We will also study linear programming and understand the role that it plays in the design of combinatorial algorithms. We will then go on to the study of NP-completeness and NP-hard problems, along with polynomial time approximation algorithms for these hard problems.