1425:【例题4】加工生产调度
时间限制: 1000 ms 内存限制: 65536 KB
提交数: 2662 通过数: 689
【题目描述】
某工厂收到了 n 个产品的订单,这 n 个产品分别在 A、B 两个车间加工,并且必须先在 A 车间加工后才可以到 B 车间加工。
某个产品 i 在 A,B 两车间加工的时间分别为Ai,Bi。怎样安排这 n 个产品的加工顺序,才能使总的加工时间最短。
这里所说的加工时间是指:从开始加工第一个产品到最后所有的产品都已在 A,B 两车间加工完毕的时间。
【输入】
第一行仅—个数据 n ,表示产品的数量;
接下来 n 个数据是表示这 n 个产品在 A 车间加工各自所要的时间;
最后的 n 个数据是表示这 n 个产品在 B 车间加工各自所要的时间。
【输出】
第一行一个数据,表示最少的加工时间;
第二行是一种最小加工时间的加工顺序。
【输入样例】
5
3 5 8 7 10
6 2 1 4 9
【输出样例】
34
1 5 4 2 3
【提示】
对于100%的数据, 0 < n < 10000,所有数值皆为整数。
参考:参考Johnson算法
修订:
思路:Johnson算法:设N1为a<b的作业集合,N2为a>=b的作业集合,将N1的作业按a非降序排序,N2的作业按b非增序排序,则N1作业接N2作业构成最优顺序。
原因:我们第一件物品加工b机器肯定会等,所以就让a机器开始加工的物品时间最短,而我们B机器最后加工完成肯定是A机器在等,所以让B机器最后加工完的时间尽可能短
oj:https://loj.ac/s/1052091
#include <bits/stdc++.h>
#define ll long long
#define PII pair<int,int>
using namespace std;
const int N=1e6+5;
struct node
{
int x,id;
bool operator<(const node &t)const
{
return x<t.x;
}
}c[N];
int n,a[N],b[N],f[N];//f[]存储编号
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin >> n;
for(int i=1;i<=n;i++)
cin >> a[i];
for(int i=1;i<=n;i++)
cin >> b[i];
//拆分成两个集合ai<bi和ai>=bi
for(int i=1;i<=n;i++)
{
c[i].x=min(a[i],b[i]);
c[i].id=i;
}
//因为排序,所以下标(存储位置)!=编号,所以要id(编号)
sort(c+1,c+n+1);
int l=1,r=n;
for(int i=1;i<=n;i++)//i是下标(存储位置)
{
if(c[i].x==a[c[i].id])
{
f[l++]=c[i].id;
}
else
{
f[r--]=c[i].id;
}
}
int ta=0,tb=0;
for(int i=1;i<=n;i++)
{
ta+=a[f[i]];
if(tb<ta)
tb=ta;
tb+=b[f[i]];
}
cout << tb << endl;
for(int i=1;i<=n;i++)
{
printf("%d ",f[i]);
}
return 0;
}