經典問題:流水線排程(51nod)
阿新 • • 發佈:2019-01-05
基準時間限制:1 秒 空間限制:131072 KB 分值: 40 難度:4級演算法題
收藏
關注
N個作業{1,2,…,n}要在由2臺機器M1和M2組成的流水線上完成加工。每個作業加工的順序都是先在M1上加工,然後在M2上加工。M1和M2加工作業i所需的時間分別為a[i]和b[i]。你可以安排每個作業的執行順序,使得從第一個作業在機器M1上開始加工,到最後一個作業在機器M2上加工完成所需的時間最少。求這個最少的時間。
Input
Output
第1行:1個數N,表示作業的數量。(2 <= N <= 50000) 第2 - N + 1行:每行兩個數,中間用空格分隔,表示在M1和M2上加工所需的時間a[i], b[i]。(1 <= a[i], b[i] <= 10000)。
輸出完成所有作業所需的最少時間。Input示例
4 3 7 2 1 1 1 4 2Output示例
14
Johnson演算法:
①:將任務分為兩類,A類任務先加工時間短,B類任務再加工時間短(or一樣長)
②:兩類任務分別排序,其中A類按先加工時間從短到長排序,B類按再加工時間從長到短排序
③:合併兩類,將第二類任務接到第一類任務後面,此時任務的順序最佳
④:遍歷所有任務,計算總耗時
#include<stdio.h> #include<algorithm> using namespace std; typedef struct { int a; int b; }Task; Task A[50005], B[50005]; bool cmpA(Task a, Task b) { if(a.a<b.a) return 1; return 0; } bool cmpB(Task a, Task b) { if(a.b>b.b) return 1; return 0; } int main(void) { int i, n, a, b, ans, sum, posA, posB, sumA, sumB; posA = posB = sumA = sumB = 0; scanf("%d", &n); for(i=1;i<=n;i++) { scanf("%d%d", &a, &b); if(a<b) { A[++posA].a = a; A[posA].b = b; sumA += b; } else { B[++posB].a = a; B[posB].b = b; sumB += a; } } sort(A+1, A+posA+1, cmpA); sort(B+1, B+posB+1, cmpB); for(i=1;i<=posB;i++) A[++posA] = B[i]; ans = A[1].a+A[1].b; sum = A[1].a; for(i=2;i<=posA;i++) { sum += A[i].a; ans = max(sum, ans)+A[i].b; } printf("%d\n", ans); return 0; }