题目描述
某工厂收到了 n 个产品的订单,这 n 个产品分别在 A,B 两个车间加工,并且必须先在 A 车间加工后才可以到 B 车间加工。
某个产品 i 在 A,B 两车间加工的时间分别为
A
i
,
B
i
{A_i},{B_i}
Ai,Bi.
怎样安排这 n 个产品的加工顺序,才能使总的加工时间最短。
这里所说的加工时间是指:从开始加工第一个产品到最后所有的产品都已在 A,B 两车间加工完毕的时间。
输入格式
第一行仅—个整数 n,表示产品的数量。
接下来一行 n 个整数是表示这 n 个产品在 A 车间加工各自所要的时间。
最后的 n 个整数是表示这 n 个产品在 B 车间加工各自所要的时间。
输出格式
第一行一个整数,表示最少的加工时间。
第二行是一种最小加工时间的加工顺序。
输入输出样例
输入#1
5
3 5 8 7 10
6 2 1 4 9
输出#1
34
1 5 4 2 3
思路
时间复杂度O
(
n
l
o
g
n
)
{(nlogn)}
(nlogn)(相较一本通上的更优秀 )
贪心:以样例数据为例:
(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)//mi=min(ai,bi)
排序之后为:(m3, m2, m1, m4, m5) //mi从小到大排序
1 2 3 4 9
处理m3,因为m3=b3,所以产品3安排在后面(,3),//从后往前
处理m2,因为m2=b2,所以产品2排在后面(,2,3),//从后往前
处理m1,因为m1=a1,所以产品1安排在前面(1,2,3), //从前往后
处理m4,因为m4=b4,所以产品4安排在后面(1,4,2,3)//从后往前
处理m5,因为m5=b5,所以产品5安排在后面(1,5,4,2,3). //从前往后
从而得到加工的顺序1,5,4,2,3.计算出最短的加工时间34.
即在A机器上加工时间短的任务应优先,而在B机器上加工时间短的务应该排在后面.
代码
#include<bits/stdc++.h>
using namespace std;
int n;
int po[2002],ans;
int aa[2002],bb[2002];
struct zb{
int a,b,mi,ha;}t[2002];
bool comp(const zb &a,const zb &b)
{
return a.mi<b.mi;
}//排序
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
cin>>t[i].a;
aa[i]=t[i].a;//用于记录数组原始状态
}
for(int i=1;i<=n;i++)
{
cin>>t[i].b;
bb[i]=t[i].b;//用于记录数组原始状态
}
for(int i=1;i<=n;i++)
{
t[i].ha=i;
t[i].mi=min(t[i].a,t[i].b);//比较时间,A短靠前,B短靠后.
}
sort(t+1,t+n+1,comp);//按t[i].mi从小到大排序
int l=1,r=n;
for(int i=1;i<=n;i++)
{
if(t[i].mi==t[i].a)
po[l++]=t[i].ha;
else po[r--]=t[i].ha;
}//安排最佳生产顺序
int kk=0,tt=0;
for(int i=1;i<=n;i++)
{
kk+=aa[po[i]];//记录A工作的时间
if(tt<kk)tt=kk;//记录上B前等的时间
tt+=bb[po[i]];//累加至总时间
}
printf("%d\n",tt);
for(int i=1;i<=n;i++)
printf("%d ",po[i]);
return 0;
}