加工生产调度
D14559. 加工生产调度
时间限制:1.0s 内存限制:256.0MB
输入文件名:test.in 输出文件名:test.out
问题描述
某工厂收到了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
思路:
几乎没有思路。
主观上整体来说要保证A机没有任何工作间隙,B的工作间隙尽可能小,然而就真的只能想到这么多,样例手工模拟然而失败了。想去提高篇上找找思路然后就,,,看到原题了。
可以发现有两段不得不浪费的空闲时间:第一个工件的A工序,在B机器上是一段空闲,而B机器的最后一个工序在A机器上也必然是空闲的。如此尽量分配这两段最小。
贪心策略:定义Mi = min(ai,bi),然后将M升序排列,从1-n选取,如果mi = ai,将该工件从前向后安排工序,反之从后向前,如此得到一个工作顺序,然后模拟就好了。
策略证明:
奥赛一本通上有完整的证明,讲不清楚真的很长很难,最后可以得到一个式子
min(bj,ai) <= min(bi,aj)
即所谓的JonhSon算法的数学表达式。也就是说在其成立的的条件下任务Ji安排在Jj之前可以得到最优解。
Code:
#include<bits/stdc++.h>
#define tim first
#define id second
using namespace std;
int ans[1010], ta[1010], tb[1010];
pair<int, int> m[1010];
int n;
void readp() {
cin >> n;
for (int i = 1; i <= n; i++)
cin >> ta[i];
for (int i = 1; i <= n; i++)
cin >> tb[i];
}
void work() {
for (int i = 1; i <= n; i++) {
m[i].tim = min(ta[i], tb[i]);
m[i].id = i;
}
sort(m + 1, m + n + 1);
int l = 0, r = n + 1;
for (int i = 1; i <= n; i++) {
if (m[i].tim == ta[m[i].id]) {
l ++;
ans[l] = m[i].id;
}
else {
r --;
ans[r] = m[i].id;
}
}
int tia = 0, tib = 0;
for (int i = 1; i <= n; i++) {
tia += ta[ans[i]];
if (tia > tib)
tib = tia;
tib += tb[ans[i]];
}
cout << tib << endl;
}
int main(){
freopen("test.in","r",stdin);
freopen("test.out","w",stdout);
readp();
work();
return 0;
}