Approximation Algorithms for NP-Hard Problems