-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathCampus_1066.java
More file actions
122 lines (102 loc) · 3.7 KB
/
Campus_1066.java
File metadata and controls
122 lines (102 loc) · 3.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
import java.util.*;
class Campus_1066 {
// My first solution: backtrack (brutal force)
// Time: O(M**N), M = bikes.length, N = workers.length
// Space: O(M)
/*
private int res;
public int assignBikes(int[][] workers, int[][] bikes) {
res = Integer.MAX_VALUE;
backtrack(workers, bikes, 0, new boolean[bikes.length], 0);
return res;
}
private int distance(int[] w, int[] b) {
return Math.abs(w[0] - b[0]) + Math.abs(w[1] - b[1]);
}
private void backtrack(int[][] workers, int[][] bikes, int idx, boolean[] bikesUsed, int sum) {
if (idx == workers.length) {
res = Math.min(res, sum);
return;
}
if (sum >= res) return; // pruning
for (int j = 0; j < bikes.length; j++) {
if (bikesUsed[j]) continue;
bikesUsed[j] = true;
backtrack(workers, bikes, idx + 1, bikesUsed, sum + distance(workers[idx], bikes[j]));
bikesUsed[j] = false;
}
}
*/
// Rewrite most voted solution using DP
// Time: O(M N 2**M), Space: O(N 2**M)
/*
public int assignBikes(int[][] workers, int[][] bikes) {
int res = Integer.MAX_VALUE;
int N = workers.length;
int M = bikes.length;
int[][] dp = new int[N + 1][1 << M];
for (int i = 0; i < N; i++) {
Arrays.fill(dp[i + 1], Integer.MAX_VALUE);
for (int s = 0; s < 1 << (i == 0 ? 0 : M); s++) {
if (dp[i][s] < Integer.MAX_VALUE) {
for (int j = 0; j < M; j++) {
if ((s & (1 << j)) != 0) continue;
int ns = s | (1 << j);
dp[i + 1][ns] = Math.min(dp[i + 1][ns], dp[i][s] + distance(workers[i], bikes[j]));
}
}
}
}
for (int v : dp[N]) res = Math.min(res, v);
return res;
}
private int distance(int[] w, int[] b) {
return Math.abs(w[0] - b[0]) + Math.abs(w[1] - b[1]);
}
*/
// Rewrite second voted solution from lee215: Priority Queue (I think it is like BFS)
class Tuple implements Comparable<Tuple> {
int dist, idx, state;
Tuple(int _dist, int _idx, int _state) {
dist = _dist;
idx = _idx;
state = _state;
}
@Override
public int compareTo(Tuple that) {
return this.dist - that.dist;
}
@Override
public int hashCode() {
int res = 17;
res = res * 31 + Integer.hashCode(idx);
res = res * 31 + Integer.hashCode(state);
return res;
}
@Override
public boolean equals(Object o) {
if (!(o instanceof Tuple)) return false;
if (o == this) return true;
Tuple t = (Tuple)o;
return this.idx == t.idx && this.state == t.state;
}
}
private int distance(int[] w, int[] b) {
return Math.abs(w[0] - b[0]) + Math.abs(w[1] - b[1]);
}
public int assignBikes(int[][] workers, int[][] bikes) {
PriorityQueue<Tuple> pq = new PriorityQueue<>();
Set<Tuple> seen = new HashSet<>();
pq.add(new Tuple(0, 0, 0));
int res = 0;
while (true) {
Tuple tuple = pq.poll();
if (seen.contains(tuple)) continue;
seen.add(tuple);
if (tuple.idx == workers.length) return tuple.dist;
for (int j = 0; j < bikes.length; j++) {
if ((tuple.state & (1 << j)) == 0)
pq.add(new Tuple(tuple.dist + distance(workers[tuple.idx], bikes[j]), 1 + tuple.idx, tuple.state | (1 << j)));
}
}
}