79 lines
2.2 KiB
C++
79 lines
2.2 KiB
C++
#include <algorithm>
|
|
#include <cassert>
|
|
#include <vector>
|
|
|
|
class Solution {
|
|
struct job_t {
|
|
int start;
|
|
int end;
|
|
int profit;
|
|
|
|
auto operator<=>(const job_t &other) const {
|
|
if (start != other.start) {
|
|
return start <=> other.start;
|
|
}
|
|
|
|
if (end != other.end) {
|
|
return end <=> other.end;
|
|
}
|
|
|
|
return profit <=> other.profit;
|
|
}
|
|
};
|
|
|
|
int find(const std::vector<job_t> &jobs, std::vector<int> &dp,
|
|
std::size_t i) {
|
|
// out of bounds
|
|
if (i >= jobs.size()) {
|
|
return 0;
|
|
}
|
|
|
|
// already precomputed
|
|
if (dp[i] != -1) {
|
|
return dp[i];
|
|
}
|
|
|
|
auto next_index =
|
|
std::lower_bound(jobs.begin(), jobs.end(), jobs[i],
|
|
[](const job_t &next, const job_t ¤t) {
|
|
return next.start < current.end;
|
|
}) -
|
|
jobs.begin();
|
|
|
|
int if_picked = jobs[i].profit + find(jobs, dp, next_index);
|
|
int if_skipped = find(jobs, dp, i + 1);
|
|
dp[i] = std::max(if_picked, if_skipped);
|
|
|
|
return dp[i];
|
|
}
|
|
|
|
public:
|
|
int jobScheduling(const std::vector<int> &startTime,
|
|
const std::vector<int> &endTime,
|
|
const std::vector<int> &profit) {
|
|
std::vector<job_t> jobs;
|
|
for (auto i = 0u; i < profit.size(); ++i) {
|
|
jobs.push_back({startTime[i], endTime[i], profit[i]});
|
|
}
|
|
std::sort(jobs.begin(), jobs.end());
|
|
|
|
std::vector<int> dp(profit.size(), -1);
|
|
find(jobs, dp, 0);
|
|
|
|
return dp[0];
|
|
}
|
|
};
|
|
|
|
int main() {
|
|
Solution s;
|
|
|
|
assert(s.jobScheduling(std::vector{1, 2, 3, 3}, std::vector{3, 4, 5, 6},
|
|
std::vector{50, 10, 40, 70}) == 120);
|
|
assert(s.jobScheduling(std::vector{1, 2, 3, 4, 6},
|
|
std::vector{3, 5, 10, 6, 9},
|
|
std::vector{20, 20, 100, 70, 60}) == 150);
|
|
assert(s.jobScheduling(std::vector{1, 1, 1}, std::vector{2, 3, 4},
|
|
std::vector{5, 6, 4}) == 6);
|
|
|
|
return 0;
|
|
}
|