This course serves as an introduction to algorithm design at the graduate level. It is a foundational course, appropriate for students in computer science, computer engineering, and mathematics, but is also of interest to students looking for research topics in the theory of algorithms. We cover both topics normally discussed in an undergraduate algorithms courses, as well as some more advanced topics. Some sample topics are: standard algorithmic paradigms such as greedy, local search and dynamic programming algorithms, and precise models for them; combinatorial and convex optimization, including the theory of linear programming, online optimization, and stochastic optimization; streaming algorithms; randomized algorithms; primal-dual algorithms; approximation algorithms; approximate near neighbour search; and mechanism design.