Search code examples
arraysalgorithmsummax

Finding max sum with operation limit


As an input i'm given an array of integers (all positive). Also as an input i`m given a number of "actions". The goal is to find max possible sum of array elements with given number of actions. As an "action" i can either:

  1. Add current element to sum
  2. Move to the next element

We are starting at 0 position in array. Each element could be added only once. Limitation are:

  1. 2 < array.Length < 20
  2. 0 < number of "actions" < 20

It seems to me that this limitations essentially not important. Its possible to find each combination of "actions", but in this case complexity would be like 2^"actions" and this is bad...))

Examples:

array = [1, 4, 2], 3 actions. Output should be 5. In this case we added zero element, moved to first element, added first element.

array = [7, 8, 9], 2 actions. Output should be 8. In this case we moved to the first element, then added first element.

Could anyone please explain me the algorithm to solve this problem? Or at least the direction in which i shoudl try to solve it.

Thanks in advance


Solution

  • Here is another DP solution using memoization. The idea is to represent the state by a pair of integers (current_index, actions_left) and map it to the maximum sum when starting from the current_index, assuming actions_left is the upper bound on actions we are allowed to take:

    from functools import lru_cache
    
    def best_sum(arr, num_actions):
      'get best sum from arr given a budget of actions limited to num_actions'
    
      @lru_cache(None)
      def dp(idx, num_actions_):
        'return best sum starting at idx (inclusive)'
        'with number of actions = num_actions_ available'
        # return zero if out of list elements or actions
        if idx >= len(arr) or num_actions_ <= 0:
          return 0
        # otherwise, decide if we should include current element or not
        return max(
            # if we include element at idx
            # we spend two actions: one to include the element and one to move 
            # to the next element
            dp(idx + 1, num_actions_ - 2) + arr[idx],
            # if we do not include element at idx
            # we spend one action to move to the next element
            dp(idx + 1, num_actions_ - 1)
            )
      
      return dp(0, num_actions)
    

    I am using Python 3.7.12.