加工生产调度
【题目描述】
某工厂收到了n个产品的订单,这n个产品分别在A、B两个车间加工,并且必须先在A车间加工后才可以到B车间加工。
某个产品i在A、B两车间加工的时间分别为Ai、Bi。询问怎样安排这n个产品的加工顺序,才能使总的加工时间最短。这里所说的加工时间是指:从开始加工第一个产品到最后所有的产品都已在A、B两车间加工完毕的时间。
【输入描述】
第一行输入一个整数n(0 < n < 1000),表示产品的数量;
第二行输入n个整数,表示这n个产品在A车间加工各自所要的时间;
第三行输入n个整数,表示这n个产品在B车间加工各自所要的时间。
【输出描述】
输出一个数,表示最少的加工时间。
【样例输入】
5
3 5 8 7 10
6 2 1 4 9
【样例输出】
34
源代码: #include<cstdio> #include<algorithm> using namespace std; int n,A[1001],B[1001],C[1001],T[1001]; struct Node { int Num,Time; bool Flag; }i[1001]; bool Rule(Node t1,Node t2) { return t1.Time<t2.Time; } void Johnson() { for (int a=1;a<=n;a++) { if (A[a]>B[a]) { i[a].Flag=true; i[a].Time=B[a]; } else { i[a].Flag=false; i[a].Time=A[a]; } i[a].Num=a; } sort(i+1,i+n+1,Rule); int Left=0,Right=n+1; for (int a=1;a<=n;a++) if (i[a].Flag) C[--Right]=i[a].Num; else C[++Left]=i[a].Num; } int main() { scanf("%d",&n); for (int a=1;a<=n;a++) scanf("%d",&A[a]); for (int a=1;a<=n;a++) scanf("%d",&B[a]); Johnson(); for (int a=1;a<=n;a++) T[a]=T[a-1]+A[C[a]]; int Ans=T[1]+B[C[1]]; //第一段比较特殊。 for (int a=2;a<=n;a++) Ans=max(Ans,T[a])+B[C[a]]; //将连续的A[i]与A[i-1]+B[i-1]作比较。 printf("%d",Ans); return 0; } /* 虽然做出来了,但这Johnson算法求流水作业调度问题依然是云里雾里。 算法正确性的证明依旧不懂。 以样例数据为例: (A1,A2,A3,A4,A5)=(3,5,8,7,10) (B1,B2,B3,B4,B5)=(6,2,1,4,9) 则最小值集合(M1,M2,M3,M4,M5)=(3,2,1,4,9) 排序之后为:(M3,M2,M1,M4,M5) 进行顺序处理: M3=B3,所以M3安排在后面( , , , ,3); M2=B2,所以M2安排在后面( , , ,2,3); M1=A1,所以M1安排在前面(1, , ,2,3); M4=B4,所以M4安排在后面(1, ,4,2,3); M5=B5,所以M5安排在后面(1,5,4,2,3); 从而得到加工顺序为:1,5,4,2,3。 计算出最短的加工时间34。 */