Program to find minimum bus fare for travelling all days in Python?

When traveling by bus on specific days, we need to find the minimum cost using three ticket types: 1-day pass ($2), 7-day pass ($7), and 30-day pass ($25). This is a classic dynamic programming problem where we optimize the cost for each day.

Problem Understanding

Given a list of travel days, we need to choose the best combination of tickets. For example, if we travel on days [1, 3, 5, 6, 28], buying a 7-day pass covers days 1-7, and a 1-day pass for day 28 gives us a total cost of $9.

Algorithm Steps

  • Create a DP array where dp[i] represents minimum cost up to day i

  • For each day, if it's a travel day, calculate the minimum cost using three options:

    • Buy 1-day pass: dp[i-1] + $2

    • Buy 7-day pass: dp[i-7] + $7 (if i ? 7)

    • Buy 30-day pass: dp[i-30] + $25 (if i ? 30)

  • If it's not a travel day, carry forward the previous cost

Implementation

def min_bus_fare(days):
    if not days:
        return 0
    
    n = max(days)
    travel_days = set(days)
    
    # dp[i] represents minimum cost to travel up to day i
    dp = [0] * (n + 1)
    
    for i in range(1, n + 1):
        if i in travel_days:
            # Option 1: Buy 1-day pass
            cost1 = dp[i - 1] + 2
            
            # Option 2: Buy 7-day pass (if applicable)
            cost7 = dp[max(0, i - 7)] + 7
            
            # Option 3: Buy 30-day pass (if applicable)
            cost30 = dp[max(0, i - 30)] + 25
            
            dp[i] = min(cost1, cost7, cost30)
        else:
            # Not a travel day, carry forward previous cost
            dp[i] = dp[i - 1]
    
    return dp[n]

# Test the function
days = [1, 3, 5, 6, 28]
result = min_bus_fare(days)
print(f"Minimum cost for days {days}: ${result}")
Minimum cost for days [1, 3, 5, 6, 28]: $9

Step-by-Step Trace

For days [1, 3, 5, 6, 28], here's how the algorithm works:

def min_bus_fare_with_trace(days):
    if not days:
        return 0
    
    n = max(days)
    travel_days = set(days)
    dp = [0] * (n + 1)
    
    print(f"Travel days: {sorted(days)}")
    print(f"DP array size: {n + 1}")
    
    for i in range(1, n + 1):
        if i in travel_days:
            cost1 = dp[i - 1] + 2
            cost7 = dp[max(0, i - 7)] + 7
            cost30 = dp[max(0, i - 30)] + 25
            
            dp[i] = min(cost1, cost7, cost30)
            print(f"Day {i}: costs[1-day: {cost1}, 7-day: {cost7}, 30-day: {cost30}] ? min: {dp[i]}")
        else:
            dp[i] = dp[i - 1]
    
    return dp[n]

# Trace example
days = [1, 3, 5, 6, 28]
result = min_bus_fare_with_trace(days)
print(f"\nFinal minimum cost: ${result}")
Travel days: [1, 3, 5, 6, 28]
DP array size: 29
Day 1: costs[1-day: 2, 7-day: 7, 30-day: 25] ? min: 2
Day 3: costs[1-day: 4, 7-day: 7, 30-day: 25] ? min: 4
Day 5: costs[1-day: 6, 7-day: 7, 30-day: 25] ? min: 6
Day 6: costs[1-day: 8, 7-day: 7, 30-day: 25] ? min: 7
Day 28: costs[1-day: 9, 7-day: 9, 30-day: 25] ? min: 9

Final minimum cost: $9

Alternative Test Cases

# Test different scenarios
test_cases = [
    [1, 2, 3, 4, 5, 6, 7],      # Consecutive 7 days
    [1, 15, 30],                # Scattered days
    [1, 2, 4, 5, 6, 7, 8, 9, 15, 16, 25, 26, 27, 28, 29, 30]  # Mixed pattern
]

for i, days in enumerate(test_cases):
    cost = min_bus_fare(days)
    print(f"Test case {i+1}: days {days}")
    print(f"Minimum cost: ${cost}\n")
Test case 1: days [1, 2, 3, 4, 5, 6, 7]
Minimum cost: $7

Test case 2: days [1, 15, 30]
Minimum cost: $6

Test case 3: days [1, 2, 4, 5, 6, 7, 8, 9, 15, 16, 25, 26, 27, 28, 29, 30]
Minimum cost: $25

Conclusion

This dynamic programming solution efficiently finds the minimum bus fare by considering all ticket options at each travel day. The algorithm has O(n) time complexity where n is the maximum day number, making it optimal for this type of cost optimization problem.

Updated on: 2026-03-25T12:09:05+05:30

1K+ Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements