LeetCode/cpp/maximum-profit-in-job-scheduling.cpp

80 lines
2.2 KiB
C++
Raw Permalink Normal View History

#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 &current) {
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;
}