给我们N个作业,编号为1到N。对于每个活动,让Ti表示完成该作业所需的天数。对于开始上班工作i之前的每一天的延迟,都会导致Li的损失。
我们需要找到完成作业的顺序,以使总体损失降到最低。我们一次只能做一份工作。
如果可能有多个这样的解决方案,那么我们需要按字典顺序给出最小的排列(即最早按字典顺序排列)。
例子:
Input : L = {3, 1, 2, 4} and
T = {4, 1000, 2, 5}
Output : 3, 4, 1, 2
Explanation: We should first complete
job 3, then jobs 4, 1, 2 respectively.
Input : L = {1, 2, 3, 5, 6}
T = {2, 4, 1, 3, 2}
Output : 3, 5, 4, 1, 2
Explanation: We should complete jobs
3, 5, 4, 1 and then 2 in this order.
让我们考虑两个极端情况,并从中推论出一般情况的解决方案。
- 所有作业都需要相同的时间才能完成,即所有i的Ti = k。由于所有作业都需要花费相同的时间才能完成,因此我们应该首先选择损失(Li)大的作业。我们应该选择损失最大的工作,并尽早完成这些工作。
因此,这是一个贪婪算法。仅基于Li对作业进行降序排序。 - 所有工作都有相同的罚款。由于所有工作都受到相同的惩罚,因此我们将首先执行这些工作,这将花费更少的时间来完成工作。这将使总延迟最小化,因此也将造成的总损失最小化。
这也是一种贪婪算法。根据Ti按升序对作业进行排序。或者,我们也可以按1 / Ti的降序排序。从上述情况中,我们可以很容易地看出,我们不应该仅根据Li或Ti来对作业进行排序。相反,我们应该按照Li / Ti的比例对作业进行降序排列。
如果对作业执行稳定的排序,则可以得到按词典顺序排列的最小作业。稳定排序的一个示例是合并排序。
为了获得最准确的结果,请避免将Li除以Ti。取而代之的是比较两个比率,例如分数。要比较a / b和c / d,请比较ad和bc。
// CPP program to minimize loss using stable sort. #include
#include #include using namespace std; #define all(c) c.begin(), c.end() // Each job is represented as a pair of int and pair. // This is done to provide implementation simplicity // so that we can use functions provided by algorithm // header typedef pair > job; // compare function is given so that we can specify // how to compare a pair of jobs bool cmp_pair(job a, job b) { int a_Li, a_Ti, b_Li, b_Ti; a_Li = a.second.first; a_Ti = a.second.second; b_Li = b.second.first; b_Ti = b.second.second; // To compare a/b and c/d, compare ad and bc return (a_Li * b_Ti) > (b_Li * a_Ti); } void printOptimal(int L[], int T[], int N) { vector list; // (Job Index, Si, Ti) for (int i = 0; i < N; i++) { int t = T[i]; int l = L[i]; // Each element is: (Job Index, (Li, Ti) ) list.push_back(make_pair(i + 1, make_pair(l, t))); } stable_sort(all(list), cmp_pair); // traverse the list and print job numbers cout << "Job numbers in optimal sequence are\n"; for (int i = 0; i < N; i++) cout << list[i].first << " "; } // Driver code int main() { int L[] = { 1, 2, 3, 5, 6 }; int T[] = { 2, 4, 1, 3, 2 }; int N = sizeof(L) / sizeof(L[0]); printOptimal(L, T, N); return 0; } 输出:
Job numbers in optimal sequence are 3 5 4 1 2
时间复杂度:O(N log N)
空间复杂度:O(N)