We accumulate the cost up to and not including the cost at each step and hold the current minimum at cur and then update our pointers. We don't need to look back more than the last two results because we can only jump 1 or 2 steps.
The other way to do this is to do the "pay when you land on a step."
class Solution:
def minCostClimbingStairs(self, cost: List[int]) -> int:
n = len(cost)
prev2, prev1 = 0, 0 # dp[0], dp[1]
for i in range(2, n + 1):
# literally just compare cumulative costs
cur = min(prev1 + cost[i - 1], prev2 + cost[i - 2])
prev2, prev1 = prev1, cur
return prev1 # it's cur, but cur would go out of scope