原题说明
On a campus represented as a 2D grid, there are N
workers and M
bikes, with N <= M
. Each worker and bike is a 2D coordinate on this grid.
We assign one unique bike to each worker so that the sum of the Manhattan distances between each worker and their assigned bike is minimized.
The Manhattan distance between two points p1
and p2
is Manhattan(p1, p2) = |p1.x - p2.x| + |p1.y - p2.y|
.
Return the minimum possible sum of Manhattan distances between each worker and their assigned bike.
Example 1:
Input: workers = [[0,0],[2,1]], bikes = [[1,2],[3,3]]
Output: 6
Explanation:
We assign bike 0 to worker 0, bike 1 to worker 1. The Manhattan distance of both assignments is 3, so the output is 6.
Example 2:
Input: workers = [[0,0],[1,1],[2,0]], bikes = [[1,0],[2,2],[2,1]]
Output: 4
Explanation:
We first assign bike 0 to worker 0, then assign bike 1 to worker 1 or worker 2, bike 2 to worker 2 or worker 1. Both assignments lead to sum of the Manhattan distances as 4.
Note:
0 <= workers[i][0], workers[i][1], bikes[i][0], bikes[i][1] < 1000
- All worker and bike locations are distinct.
1 <= workers.length <= bikes.length <= 10
解题思路
我们先用一个二维矩阵记录每个工人到每辆车的距离,dp[i][j] = distance
就表示工人i
和车j
的距离为distance
。
这样我们把问题就转化为:在二维矩阵里每一行取一个数,同时每个数不能有相同的列,要求让所有取出的数之和最小。
如果用简单的暴力破解,用dfs
把所有取法都遍历一遍,时间复杂度是O(N!)
。这里是不能通过测试的。
因此我们需要用backtracking + memoization
的方法做优化。用一个数state
表示已经选取了的bike
的组合。这样memo[state]
就表示在当前选取的自行车组合下,之后能得到的最小和。
这样我们就能从后往前递归,减少重复计算的,大大降低时间复杂度。
这是一种bottom up
的思想。
这里有一个技巧,我们用二进制的思想构造state
。因为自行车的数量不超过10
个,那么在第i
位上,如果等于1
,则说明第i
辆自行车被选择了,否则就是没被选择。
示例代码 (cpp)
1 | class Solution { |
示例代码 (java)
1 | class Solution { |
示例代码 (python)
1 | class Solution: |
复杂度分析
M
为workers
数量,N
为bikes
数量
时间复杂度: state
一共有2^N
,每个state
至多被计算一遍,因此这里是O(2^N)
空间复杂度: 距离的cache
可以忽略不计,主要开销在memo
上,因此这里是O(2^N)
视频讲解
我们在Youtube上更新了视频讲解,欢迎关注!