#include #include #include 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 &jobs, std::vector &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 &startTime, const std::vector &endTime, const std::vector &profit) { std::vector 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 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; }