回溯DFS
class Solution {
int[] delta;
int ans = 0, cnt = 0, zero, n;
public int maximumRequests(int n, int[][] requests) {
delta = new int[n];
zero = n;
this.n = n;
dfs(requests, 0);
return ans;
}
public void dfs(int[][] requests, int pos) {
if (pos == requests.length) {
if (zero == n) {
ans = Math.max(ans, cnt);
}
return;
}
dfs(requests, pos + 1);
int z = zero;
++cnt;
int[] r = requests[pos];
int x = r[0], y = r[1];
zero -= delta[x] == 0 ? 1 : 0;
--delta[x];
zero += delta[x] == 0 ? 1 : 0;
zero -= delta[y] == 0 ? 1 : 0;
++delta[y];
zero += delta[y] == 0 ? 1 : 0;
dfs(requests, pos + 1);
--delta[y];
++delta[x];
--cnt;
zero = z;
}
}
二进制枚举
思路
- 用二进制数mask表示所有的请求
- mask中1的个数表示已接受的请求数
- 枚举每个mask
- 剪枝:1的个数小于目前
最多可达成的换楼请求数目
,则continue
- 对于每个mask,
delta
都是独立的,皆初始化为0 - 循环
已接受的请求们
,更新delta - 更新答案 when 满足条件:delta所有值皆为0
class Solution {
public int maximumRequests(int n, int[][] requests) {
int[] delta = new int[n];
int ans = 0, m = requests.length;
for (int mask = 0; mask < (1 << m); ++mask) {
int cnt = Integer.bitCount(mask);
if (cnt <= ans) {
continue;
}
Arrays.fill(delta, 0);
for (int i = 0; i < m; ++i) {
if ((mask & (1 << i)) != 0) {
++delta[requests[i][0]];
--delta[requests[i][1]];
}
}
boolean flag = true;
for (int x : delta) {
if (x != 0) {
flag = false;
break;
}
}
if (flag) {
ans = cnt;
}
}
return ans;
}
}