Program to find maximum average pass ratio in Python

Suppose we have a list of classes where classes[i] = [pass_i, total_i] represents the number of students who passed and the total number of students in the ith class respectively. We also have extra brilliant students guaranteed to pass any exam they're assigned to. We need to assign these extra students to maximize the average pass ratio across all classes.

The pass ratio of a class is passed_students / total_students. The average pass ratio is the sum of all class ratios divided by the number of classes.

Algorithm Approach

We use a greedy approach with a max-heap to always assign the next student to the class that gives the maximum improvement in pass ratio ?

  • Calculate the potential improvement for each class if we add one student

  • Use a max-heap to efficiently find the class with maximum improvement

  • Assign students one by one to the class with highest improvement

  • Update the heap after each assignment

Implementation

import heapq

def solve(classes, extra):
    # Calculate improvement for each class: current_ratio - new_ratio_after_adding_one_student
    # Use negative values for max-heap (Python has min-heap by default)
    h = [(-((a + 1) / (b + 1) - a / b), a, b) for a, b in classes]
    heapq.heapify(h)
    
    # Assign extra students one by one
    while extra > 0:
        # Get class with maximum improvement potential
        neg_improvement, a, b = heapq.heappop(h)
        
        # Add one student to this class
        a, b = a + 1, b + 1
        
        # Calculate new improvement and push back to heap
        new_improvement = -((a + 1) / (b + 1) - a / b)
        heapq.heappush(h, (new_improvement, a, b))
        
        extra -= 1
    
    # Calculate final average pass ratio
    return sum(a / b for neg_improvement, a, b in h) / len(h)

# Test the solution
classes = [[2,3],[4,6],[3,3]]
extra = 3
result = solve(classes, extra)
print(f"Maximum average pass ratio: {result:.5f}")
Maximum average pass ratio: 0.83810

How It Works

Let's trace through the example step by step ?

def solve_with_trace(classes, extra):
    print(f"Initial classes: {classes}")
    print(f"Extra students to assign: {extra}")
    
    # Calculate initial improvements
    h = [(-((a + 1) / (b + 1) - a / b), a, b) for a, b in classes]
    heapq.heapify(h)
    
    print("\nStep-by-step assignment:")
    step = 1
    
    while extra > 0:
        # Get class with maximum improvement
        neg_improvement, a, b = heapq.heappop(h)
        improvement = -neg_improvement
        
        print(f"Step {step}: Assign to class [{a}, {b}], improvement: {improvement:.5f}")
        
        # Add one student
        a, b = a + 1, b + 1
        
        # Push back updated class
        new_improvement = -((a + 1) / (b + 1) - a / b)
        heapq.heappush(h, (new_improvement, a, b))
        
        extra -= 1
        step += 1
    
    # Calculate final result
    final_ratios = [a / b for neg_improvement, a, b in h]
    average = sum(final_ratios) / len(final_ratios)
    
    print(f"\nFinal classes: {[(a, b) for neg_improvement, a, b in h]}")
    print(f"Individual ratios: {[f'{ratio:.5f}' for ratio in final_ratios]}")
    print(f"Average pass ratio: {average:.5f}")
    
    return average

# Test with trace
classes = [[2,3],[4,6],[3,3]]
extra = 3
solve_with_trace(classes, extra)
Initial classes: [[2, 3], [4, 6], [3, 3]]
Extra students to assign: 3

Step-by-step assignment:
Step 1: Assign to class [2, 3], improvement: 0.08333
Step 2: Assign to class [3, 4], improvement: 0.05000
Step 3: Assign to class [4, 6], improvement: 0.04762

Final classes: [(4, 5), (5, 7), (3, 3)]
Individual ratios: ['0.80000', '0.71429', '1.00000']
Average pass ratio: 0.83810

Key Points

  • Greedy Strategy: Always assign the next student to the class with maximum improvement potential

  • Heap Usage: Min-heap with negative values simulates max-heap behavior

  • Improvement Formula: (a+1)/(b+1) - a/b calculates how much the ratio improves by adding one student

  • Time Complexity: O(extra × log(classes)) for heap operations

Conclusion

This greedy algorithm with heap optimization efficiently finds the maximum average pass ratio by always assigning students to classes with the highest improvement potential. The solution achieves optimal results in O(extra × log n) time complexity.

Updated on: 2026-03-26T14:18:05+05:30

263 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements