问题就是2台机器,n件任务,必须先在S1上做,再在S2上做。任务之间先做后做任意。求最早的完工时间。
这是一个经典问题:2台机器的情况下有多项式算法(Johnson算法),3台或以上的机器是NP-hard的。思想就是贪心,时间复杂度是O(nlogn) 。
Johnson算法
(1) 把作业按工序加工时间分成两个子集,第一个集合中在S1上做的时间比在S2上少,其它的作业放到第二个集合。先完成第一个集合里面的作业,再完成第二个集合里的作业。
(2) 对于第一个集合,其中的作业顺序是按在S1上的时间的不减排列;对于第二个集合,其中的作业顺序是按在S2上的时间的不增排列。
怎么证呢?
#include <iostream>
#include <cstdio>
#include <algorithm>
namespace std;
int maxn = 10005;
struct node{
int x,y;
8: }a[maxn],b[maxn],c[maxn];
const node &q)
10: {
return p.x < q.x;
12: }
const node &q)
14: {
return p.y > q.y;
16: }
int n;
int s1sum[maxn];
int sum;
int main()
21: {
,&n) && n)
24: {
int i=0;i<n;++i)
,&a[i].x,&a[i].y);
int len1 = 0, len2 = 0;
int i=0;i<n;++i)
29: {
if(a[i].x < a[i].y)
31: {
//子集1 x<y
33: b[len1++].y = a[i].y;
34: }
else
36: {
//子集2
38: c[len2++].y = a[i].y;
39: }
40: }
//子集1作业顺序:x不减
//子集2作业顺序:y不增
int i = len1;i<len1+len2;++i)
44: b[i] = c[i-len1];
45: s1sum[0] = 0;
int i=0;i<n;++i)
47: s1sum[i+1] = s1sum[i]+b[i].x;
48: sum = 0;
int i=0;i<n;++i)
50: {
if(sum<s1sum[i+1]) sum = s1sum[i+1]+b[i].y;
else sum+=b[i].y;
53: }
,sum);
55: }
56: }