Złodziej zatykacza lub maksymalna suma, tak że nie sąsiadują dwa elementy

Recursion :
def FindMaxSum(arr, n):
        
    def recur(arr, n):
        
        if n == 1:
            return arr[n-1]
        
        if n == 2:
            return max(arr[n-1], arr[n-2])
        
        return max(recur(arr, n-1), recur(arr, n-2) + arr[n-1])
    
    return recur(arr, n)
 
Top Down :
def FindMaxSum(arr, n):
        
    def top_down(arr, n, dp):
        
        if dp[n] != -1:
            return dp[n]
    
        dp[n] =  max(top_down(arr, n-1, dp), top_down(arr, n-2, dp) + arr[n-1])
        
        return dp[n]
    
    if n == 1:
        return arr[0]
    if n == 2:
        return max(arr[0], arr[1])
        
    dp =[-1 for i in range(n+1)]
    dp[1] = arr[0]
    dp[2] = max(arr[0], arr[1])
    
    return top_down(arr, n, dp)
  
Bottom Up :
def FindMaxSum(arr, n):
        
    def bottom_up(arr, n, dp):
        
        for i in range(2, n):
            dp[i] =  max(dp[i-1], dp[i-2] + arr[i])

    if n == 1:
        return arr[0]
    if n == 2:
        return max(arr[0], arr[1])
        
    dp =[0 for i in range(n)]
    dp[0] = arr[0]
    dp[1] = max(arr[0], arr[1])
    
    bottom_up(arr, n, dp)
    
    return dp[n-1]
Helper