We use cookies (including Google cookies) to personalize ads and analyze traffic. By continuing to use our site, you accept our Privacy Policy.

Sell Diminishing-Valued Colored Balls

Number: 1771

Difficulty: Medium

Paid? No

Companies: Groupon


Problem Description

Given an array representing the inventory of different colored balls (where each ball’s value equals the current count of that ball’s color in the inventory) and an integer orders representing the total balls to sell, find the maximum total value when selling exactly orders balls. The value of a ball decreases by one each time one is sold from a given color.


Key Insights

  • The sale of a ball reduces its future value by one, so selling higher-value balls first is optimal.
  • Sorting the inventory allows you to consider the highest values first.
  • Instead of selling one ball at a time, use an arithmetic series to sum a block of consecutive values.
  • Greedy reduction from the current maximum value to the next distinct value (or until orders run out) can be computed in O(1) per group using the arithmetic sum formula.
  • Modulo arithmetic (10^9 + 7) is necessary to avoid overflow.

Space and Time Complexity

Time Complexity: O(n log n) primarily due to sorting the inventory. Space Complexity: O(1) or O(n) depending on the sorting implementation.


Solution

We first sort the inventory in descending order. Then, we simulate the selling process in rounds. In each round, we determine how many balls at the current highest value we can sell before the value decreases to the next distinct number. This can involve selling an entire group of balls in one aggregate arithmetic sum (using the formula for the sum of an arithmetic sequence) or, if orders are fewer than the group size, selling part of the sequence. Binary search or pointer manipulation helps in grouping the balls with equal or similar value. Finally, as the results may be very large, we take the answer modulo 10^9 + 7.


Code Solutions

MOD = 10**9 + 7

def maxProfit(inventory, orders):
    # Sort the inventory in descending order
    inventory.sort(reverse=True)
    inventory.append(0)  # Adding a zero for easier calculation in the loop
    profit = 0
    n = 1  # count of colors with current inventory value
    
    # Iterate over the inventory to sell in groups
    for i in range(len(inventory) - 1):
        # Current value and next distinct value
        current, next_val = inventory[i], inventory[i+1]
        # Calculate the total number of balls we can sell if we reduce current group down to next_val
        count = n * (current - next_val)
        
        if orders >= count:
            # Sell all balls down to next distinct value
            # Use arithmetic sum formula sum from (next_val+1) to current
            total = n * (current + next_val + 1) * (current - next_val) // 2
            profit = (profit + total) % MOD
            orders -= count
        else:
            # Not enough orders to reduce all balls to next_val, so calculate how many full rows we can remove
            full, remainder = divmod(orders, n)
            sell_from = current - full
            total = n * (current + sell_from + 1) * full // 2
            profit = (profit + total + remainder * (sell_from)) % MOD
            return profit
        n += 1  # Increase group size for next iteration
    return profit

# Example usage:
print(maxProfit([2,5], 4))  # Expected output: 14
← Back to All Questions