-
Notifications
You must be signed in to change notification settings - Fork 1.6k
/
maximum-value-sum-by-placing-three-rooks-i.cpp
80 lines (76 loc) · 3.09 KB
/
maximum-value-sum-by-placing-three-rooks-i.cpp
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
// Time: O(m * n * logk + nCr((k-1)*(2*k-1)+1), k) * k) = O(m * n)
// Space: O(k * (m + n)) = O(m + n)
// heap, brute force
class Solution {
public:
long long maximumValueSum(vector<vector<int>>& board) {
static const int k = 3;
const auto& combinations = [](int n, int k, const auto& callback) {
static const auto& next_pos =
[](const auto& n, const auto& k, const auto& idxs) {
int i = k - 1;
for (; i >= 0; --i) {
if (idxs[i] != i + n - k) {
break;
}
}
return i;
};
vector<int> idxs(k);
iota(begin(idxs), end(idxs), 0);
callback(idxs);
for (int i; (i = next_pos(n, k, idxs)) >= 0;) {
++idxs[i];
for (int j = i + 1; j < k; ++j) {
idxs[j] = idxs[j - 1] + 1;
}
callback(idxs);
}
};
using Data = tuple<int, int, int>;
vector<priority_queue<Data, vector<Data>, greater<Data>>> min_heaps(size(board[0]));
for (int i = 0; i < size(board); ++i) {
priority_queue<Data, vector<Data>, greater<Data>> min_heap;
for (int j = 0; j < size(board[0]); ++j) {
min_heap.emplace(board[i][j], i, j);
if (size(min_heap) == k + 1) {
min_heap.pop();
}
}
while (!empty(min_heap)) {
const auto [v, i, j] = min_heap.top(); min_heap.pop();
min_heaps[j].emplace(v, i, j);
if (size(min_heaps[j]) == k + 1) {
min_heaps[j].pop();
}
}
}
priority_queue<Data, vector<Data>, greater<Data>> min_heap;
for (auto& h : min_heaps) {
while (!empty(h)) {
const auto x = h.top(); h.pop();
min_heap.emplace(x);
if (size(min_heap) == ((k - 1) * (2 * k - 1) + 1) + 1) { // each choice excludes at most 2k-1 candidates, we should have at least (k-1)*(2k-1)+1 candidates
min_heap.pop();
}
}
}
int64_t result = numeric_limits<int64_t>::min();
vector<Data> candidates;
while (!empty(min_heap)) {
const auto x = min_heap.top(); min_heap.pop();
candidates.emplace_back(x);
}
combinations(size(candidates), k,
[&](const vector<int>& idxs) {
const auto& [x0, x1, x2] = candidates[idxs[0]];
const auto& [y0, y1, y2] = candidates[idxs[1]];
const auto& [z0, z1, z2] = candidates[idxs[2]];
if ((x1 != y1 && y1 != z1 && z1 != x1) &&
(x2 != y2 && y2 != z2 && z2 != x2)) {
result = max(result, static_cast<int64_t>(x0) + y0 + z0);
}
});
return result;
}
};