For the love of me I still can't consistently solve dynamic programming problems. Because "write a clever brute force solution that can be cached" is so broad that there are tons of variations out there, and a slight twist can bring you out of the loop fast.
Project Euler 18. I tried 3 heuristic approaches, before accepting, that to get the real answer without brute forcing it (because it comes back later in non-brute forcable version anyway), I need to find another way. I came up with an optimal solution, but it is still not dynamic programming, which I would also consider inferior to the bottom up solution I have found.
There is only one efficient solution that can be described as bottom up, and that one is in fact dynamic programming.
A top-down solution in this case is in fact strictly worse. Why? Because while both take similar numbers of operations, in the bottom up solution you can throw away a row once you've processed the one above it. But in a top-down solution, you never know when you might call a particular recursive call again.
This is very common. In a bottom up approach, we often know when we're done with data and can throw it away. This memory savings is the reason why people try to learn a bottom up approach. But it does come with the price of trying to figure out various kinds of "tricks". (That in complicated cases, may not be findable.)