Program to find out the maximum points collectable in a game in Python

Suppose we are playing a game of cards. We are given several cards arranged linearly with a number on each of them. The numbers on the cards are randomly distributed; and at the beginning and the end of the cards, two cards are inserted with the number 1 on them. Now, in the game, we have to collect the maximum points by picking up the given cards. The cards are represented in an array 'cards' where the elements in the array represent the number of cards[i]. When we pick up card i, we collect points cards[i - 1] * cards[i] * cards[i + 1]. When we pick up a card, cards[i - 1] and cards[i + 1] become neighbors. So, from these given cards we find out the maximum points that we can collect.

So, if the input is like cards = [7, 5, 9, 10], then the output will be 1025.

Game Strategy Example

In the game, we can pick up cards in the following order ?

  • The card at index 1 (value 5) and get 7 * 5 * 9 = 315 points.
  • The card at the new index 1 (value 9) and get 7 * 9 * 10 = 630 points.
  • The card at index 1 (value 10) and get 1 * 7 * 10 = 70 points.
  • The last card (value 7) and get 1 * 7 * 1 = 7 points.

Total points = 315 + 630 + 70 + 7 = 1022 (but optimal strategy gives 1025).

Algorithm Approach

To solve this, we will follow these steps ?

  • Define a function search(). This will take x, y
    • temp := 0
    • for z in range x + 1 to y, do
      • temp := maximum of (temp, search(x, z) + search(z, y) + cards[x] * cards[z] * cards[y])
    • return temp
  • Insert values 1 and 1 at the beginning and the end of the list cards respectively
  • Return search(0, size of cards - 1)

Basic Recursive Solution

Let us see the following implementation to get better understanding ?

def solve(cards):
    def search(x, y):
        temp = 0
        for z in range(x + 1, y):
            temp = max(temp, search(x, z) + search(z, y) + cards[x] * cards[z] * cards[y])
        return temp
    
    cards = [1] + cards + [1]
    return search(0, len(cards) - 1)

print(solve([7, 5, 9, 10]))
1025

Optimized Dynamic Programming Solution

The basic recursive solution has overlapping subproblems. We can optimize it using memoization ?

def solve_optimized(cards):
    cards = [1] + cards + [1]
    n = len(cards)
    memo = {}
    
    def search(x, y):
        if (x, y) in memo:
            return memo[(x, y)]
        
        temp = 0
        for z in range(x + 1, y):
            temp = max(temp, search(x, z) + search(z, y) + cards[x] * cards[z] * cards[y])
        
        memo[(x, y)] = temp
        return temp
    
    return search(0, n - 1)

# Test with example
result = solve_optimized([7, 5, 9, 10])
print(f"Maximum points: {result}")

# Test with another example
result2 = solve_optimized([3, 1, 5, 8])
print(f"Maximum points for [3,1,5,8]: {result2}")
Maximum points: 1025
Maximum points for [3,1,5,8]: 167

How It Works

The algorithm uses the principle of dynamic programming. For each subarray from index x to y, we try picking each card z between x and y as the last card to be removed. When card z is picked last, we get:

  • Points from removing cards between x and z
  • Points from removing cards between z and y
  • Points from picking card z: cards[x] * cards[z] * cards[y]

We take the maximum of all possible choices for z.

Conclusion

This problem demonstrates the classic "burst balloons" dynamic programming pattern. The key insight is to think about which card to pick last rather than first, making the recursive structure cleaner. The memoized version significantly improves performance for larger inputs.

Updated on: 2026-03-26T16:53:57+05:30

337 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements