-
Notifications
You must be signed in to change notification settings - Fork 1.6k
/
find-the-maximum-sequence-value-of-array.cpp
92 lines (87 loc) · 3.07 KB
/
find-the-maximum-sequence-value-of-array.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
81
82
83
84
85
86
87
88
89
90
91
92
// Time: O(n * r + r^2)
// Space: O(r)
// bitmasks, prefix sum, dp
class Solution {
public:
int maxValue(vector<int>& nums, int k) {
static const int INF = numeric_limits<int>::max();
static const int MAX_MASK = 127;
const auto& is_submask = [](int a, int b) {
return (a | b) == b;
};
const auto& dp = [&](int d, int npos) {
vector<int> result(MAX_MASK + 1, npos);
vector<int> dp(MAX_MASK + 1, INF), cnt(MAX_MASK + 1, 0);
const int begin = d == 1 ? 0 : size(nums) - 1;
const int end = d == 1 ? size(nums) : -1;
for (int i = begin ; i != end; i += d) {
dp[nums[i]] = 1;
for (int mask = 0; mask <= MAX_MASK; ++mask) {
if (is_submask(nums[i], mask)) {
++cnt[mask];
}
if (dp[mask] != INF) {
dp[mask | nums[i]] = min(dp[mask | nums[i]], dp[mask] + 1);
}
}
for (int mask = 0; mask < MAX_MASK + 1; ++mask) {
if (cnt[mask] >= k && dp[mask] <= k && result[mask] == npos) {
result[mask] = i;
}
}
}
return result;
};
const auto& left = dp(1, size(nums));
const auto& right = dp(-1, -1);
for (int result = MAX_MASK; result >= 0; --result) {
for (int l = 1; l <= MAX_MASK; ++l) {
if (left[l] < right[result ^ l]) {
return result;
}
}
}
return 0;
}
};
// Time: O(n * k * r + n * r^2)
// Space: O(n * k * r)
// prefix sum, dp
class Solution_TLE {
public:
int maxValue(vector<int>& nums, int k) {
vector<vector<unordered_set<int>>> left(size(nums) + 1, vector<unordered_set<int>>(k + 1));
for (int i = 0; i < size(left); ++i) {
left[i][0].emplace(0);
}
for (int i = 0; i < size(nums); ++i) {
for (int j = 1; j < size(left[i + 1]); ++j) {
left[i + 1][j] = left[i][j];
for (const auto& x : left[i][j - 1]) {
left[i + 1][j].emplace(x | nums[i]);
}
}
}
vector<vector<unordered_set<int>>> right(size(nums) + 1, vector<unordered_set<int>>(k + 1));
for (int i = 0; i < size(right); ++i) {
right[i][0].emplace(0);
}
for (int i = size(nums) - 1; i >= 0; --i) {
for (int j = 1; j < size(right[i]); ++j) {
right[i][j] = right[i + 1][j];
for (const auto& x : right[i + 1][j - 1]) {
right[i][j].emplace(x | nums[i]);
}
}
}
int result = 0;
for (int i = k; i <= size(nums) - k; ++i) {
for (const auto& l : left[i][k]) {
for (const auto& r : right[i][k]) {
result = max(result, l ^ r);
}
}
}
return result;
}
};