//
// main.cpp
// Weighted interval scheduling
//
// Created by Longxiang Lyu on 5/31/16.
// Copyright (c) 2016 Longxiang Lyu. All rights reserved.
//
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
struct Job
{
int start;
int finish;
int weight;
Job() = default;
Job(int s, int f, int w) : start(s), finish(f), weight(w) {}
};
bool operator<(const Job &lhs, const Job &rhs)
{
return lhs.finish < rhs.finish;
}
int binary_search(const vector<Job> &jobs, int index)
{
if (index == 0)
return -1;
int left = 0, right = index - 1;
while (left <= right)
{
int mid = (left + right) / 2;
if (jobs[mid].finish <= jobs[index].start)
{
if (jobs[mid + 1].finish <= jobs[index].start)
left = mid + 1;
else
return mid;
}
else
{
right = mid - 1;
}
}
return -1;
}
int Mcompute(const vector<Job> &jobs, const vector<int> &p, vector<int> &M, int index)
{
if (index == -1)
return 0;
if (M[index] == -1)
M[index] = max(jobs[index].weight + Mcompute(jobs, p, M, p[index]), Mcompute(jobs, p, M, index - 1));
return M[index];
}
int findMaxProfit(vector<Job> &jobs, vector<Job> &solution)
{
int n = static_cast<int>(jobs.size());
sort(jobs.begin(), jobs.end()); // sort the jobs by finish time (O(nlogn))
vector<int> p(n);
for (int i = 0; i < n; ++i)
p[i] = binary_search(jobs, i); // calculate P[j] (O(nlogn))
vector<int> M(n, -1);
for (int i = n - 1; i >= 0; /* empty */)
{
if (p[i] != -1)
{
if (jobs[i].weight + M[p[i]] > M[i - 1])
{
solution.push_back(jobs[i]);
i = p[i];
}
else
{
--i;
}
}
else
{
solution.push_back(jobs[i]);
break;
}
}
return Mcompute(jobs, p, M, n - 1); // O(n)
}
int main(int argc, const char * argv[]) {
vector<Job> jobs{{1, 4, 3}, {3, 5, 2}, {0, 6, 6}, {4, 7, 3}, {3, 8, 5}, {5, 9, 4}, {6, 10, 4}, {8, 11, 3}};
vector<Job> solutions;
cout << findMaxProfit(jobs, solutions) << endl;
cout << "The jobs are: " << endl;
for (auto a : solutions)
{
cout << a.start << '\t' << a.finish << '\t' << a.weight << endl;
}
return 0;
}
Reference:
http://www.geeksforgeeks.org/weighted-job-scheduling-log-n-time/