Fair and Optimal Decision Trees: A Dynamic Programming Approach