加工生产调度

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;
}
原文地址:https://www.cnblogs.com/sun915/p/9512613.html