The shortest way to turn a branching recursion into DP is to remember: on the way in, look in a dictionary for "have I solved this before?"; on the way out, write the answer there. The rest of the code stays the same; every repeated branch of the call tree collapses into one lookup.
def best(i, memo):if i >= len(values):return 0if i not in memo:take = values[i] + best(i + 2, memo)skip = best(i + 1, memo)memo[i] = max(take, skip)return memo[i]
i and you skip the next (i + 2), leave it and you move on. Without the dictionary the calls double at every element; with it each i is worked out once.The same solution can be written with a table, back to front or front to back; here two variables are even enough, since only the last two values are needed. Write the remembering recursion first and see that it is right; simplifying comes after.