Optimize recursive algorithms by identifying overlapping subproblems and caching their results.
Write a recursive Fibonacci function, observe its slowness at N=40, then optimize it using memoization to execute instantly.