Article Categories
- All Categories
-
Data Structure
-
Networking
-
RDBMS
-
Operating System
-
Java
-
MS Excel
-
iOS
-
HTML
-
CSS
-
Android
-
Python
-
C Programming
-
C++
-
C#
-
MongoDB
-
MySQL
-
Javascript
-
PHP
-
Economics & Finance
Campus Bikes II in Python
The Campus Bikes II problem involves assigning unique bikes to workers on a 2D grid such that the total Manhattan distance is minimized. Given N workers and M bikes (where N ? M), we need to find the optimal assignment.
The Manhattan distance between two points p1 and p2 is calculated as: |p1.x - p2.x| + |p1.y - p2.y|.
Problem Example
Given workers = [[0,0],[2,1]] and bikes = [[1,2],[3,3]]:
The optimal assignment gives us a minimum total Manhattan distance of 6.
Solution Approach
We use dynamic programming with memoization and backtracking to explore all possible assignments:
- Helper function: Calculates Manhattan distance between two points
- Recursive solver: Tries assigning each available bike to the current worker
- Memoization: Stores results to avoid recalculating the same state
- Backtracking: Unmarking bikes after trying each assignment
Implementation
class Solution:
def helper(self, a, b):
"""Calculate Manhattan distance between two points"""
return abs(a[0] - b[0]) + abs(a[1] - b[1])
def solve(self, bikes, workers, bikev, i=0):
"""Recursively find minimum distance assignment"""
info = (i, tuple(bikev))
if info in self.memo:
return self.memo[info]
if i == len(workers):
return 0
temp = float('inf')
for j in range(len(bikes)):
if not bikev[j]: # If bike j is available
bikev[j] = True # Mark bike as used
current_distance = self.helper(workers[i], bikes[j])
remaining_distance = self.solve(bikes, workers, bikev, i + 1)
temp = min(temp, current_distance + remaining_distance)
bikev[j] = False # Backtrack: mark bike as available
self.memo[info] = temp
return temp
def assignBikes(self, workers, bikes):
"""Main function to assign bikes to workers"""
bikev = [False for _ in range(len(bikes))]
self.memo = {}
return self.solve(bikes, workers, bikev)
# Test the solution
solution = Solution()
workers = [[0,0],[2,1]]
bikes = [[1,2],[3,3]]
result = solution.assignBikes(workers, bikes)
print(f"Minimum total Manhattan distance: {result}")
Minimum total Manhattan distance: 6
How It Works
The algorithm works by:
- State representation: Current worker index + which bikes are used
- Base case: When all workers are assigned, return 0
- Recursive case: Try assigning each available bike to current worker
- Memoization: Cache results using (worker_index, bikes_used_tuple) as key
Time Complexity
| Aspect | Complexity | Explanation |
|---|---|---|
| Time | O(N × 2^M) | N workers, 2^M possible bike states |
| Space | O(N × 2^M) | Memoization table size |
Conclusion
This solution uses dynamic programming with memoization to efficiently solve the Campus Bikes II problem. The backtracking approach explores all possible assignments while memoization prevents redundant calculations, ensuring optimal bike-to-worker assignment with minimum total Manhattan distance.
