Maximize Valid Trains from Shared Equipment
BnsfSoftware Engineer · OnsiteLast updated
Form the maximum number of valid trains from a shared pool of locomotives and railcars, breaking ties by maximizing total railcar length.
A freight rail terminal needs to assemble trains from available equipment. You are given a fleet of locomotives and a set of railcars. Each train must be formed by selecting exactly one locomotive and a non-empty subset of railcars subject to the following operating rules:
- Equipment Exclusivity: Each locomotive and railcar can be assigned to at most one train.
- Tonnage Capacity: The sum of weights of all railcars assigned to a train cannot exceed the locomotive's pulling capacity.
- Length Constraint: The sum of lengths of all railcars assigned to a train cannot exceed
max_car_length. - Car Count Limit: Each train must contain at least
min_carsand at mostmax_carsrailcars.
Your goal is to optimize the assembly lexicographically:
- Primary Objective: Maximize the number of valid trains assembled.
- Secondary Objective: Among configurations achieving the maximum number of trains, maximize the total railcar length across all assembled trains.
Write a function optimize_train_assembly(locomotives, cars, max_car_length, min_cars, max_cars) that returns a tuple (max_trains, max_total_car_length).
Interface
def optimize_train_assembly(
locomotives: list[int],
cars: list[tuple[int, int]],
max_car_length: int,
min_cars: int,
max_cars: int
) -> tuple[int, int]:
"""
locomotives: capacities of each locomotive [cap_0, cap_1, ...]
cars: list of (weight, length) tuples for each railcar
max_car_length: maximum allowed total railcar length per train
min_cars: minimum number of cars per train
max_cars: maximum number of cars per train
Returns: (max_trains, max_total_car_length)
"""
pass
Constraints
1 <= len(locomotives) <= 61 <= len(cars) <= 141 <= locomotives[i] <= 10^71 <= weight_j, length_j <= 10^6for each car1 <= max_car_length <= 10^71 <= min_cars <= max_cars <= len(cars)
Examples
Example 1
locomotives = [100, 80]
cars = [(50, 40), (40, 30), (30, 25), (20, 20)]
max_car_length = 60
min_cars = 1
max_cars = 2
# Output: (2, 95)
# Explanation:
# Train 1 (Locomotive cap 100): Car 0 (wt 50, len 40) + Car 2 (wt 30, len 25)
# Total weight = 80 60 (Invalid! Length exceeded)
# Better configuration:
# Train 1 (Locomotive cap 100): Car 0 (wt 50, len 40) + Car 3 (wt 20, len 20)
# Weight = 70 <= 100, length = 60 <= 60 (Valid, length = 60)
# Train 2 (Locomotive cap 80): Car 2 (wt 30, len 25)
# Weight = 30 <= 80, length = 25 <= 60 (Valid, length = 25)
# Total cars = 3, total length = 85.
# An even better assignment:
# Train 1 (Locomotive cap 80): Car 1 (wt 40, len 30) + Car 3 (wt 20, len 20)
# Weight = 60 <= 80, length = 50 60 (invalid).
# If Train 1 takes Car 1 (30) + Car 2 (25) = len 55, wt 70 <= 80.
# Train 2 takes Car 0 (40) = len 40, wt 50 <= 100. Total length = 95.
Example 2
locomotives = [50]
cars = [(60, 20), (70, 30)]
max_car_length = 100
min_cars = 1
max_cars = 2
# Output: (0, 0)
# Explanation: No locomotive has sufficient capacity to pull even a single car.
Hints
Hint 1
Notice the small input limits on railcars (up to 14) and locomotives (up to 6), which makes bitmask dynamic programming or backtracking over car subsets feasible.
Hint 2
Precompute all valid car subsets (represented as bitmasks) with their total weight, total length, and car count that satisfy the length and car count constraints.
Hint 3
Use dynamic programming over `(locomotive_index, used_cars_bitmask)` or branch-and-bound search, sorting locomotives descending by capacity and maintaining lexicographically optimal pairs `(trains, length)`.
Follow-up questions
- How would you adapt the solution if trains could couple multiple locomotives together up to a consist limit of `K` locomotives per train?
- If the number of cars grows to `N = 100` but weights and lengths are identical across a small number of car types, how would you reformulate this problem?
- How would you modify the search to output the concrete assignments of cars and locomotives rather than just the counts?
Solution walkthrough is for members
Get the full walkthrough with reference code and complexity analysis, plus Kitty Coach at 300 messages a day. Hints, the code runner and community answers stay free.