题目解析:
本题是要求一个加工顺序使得总的加工时间最少,而要使加工时间最少,就是让各车间的空闲时间最少。一旦A车间开始加工,便会不停地进行加工(我们不要去管车间是否能够一直生产,因为他们有三班,可以24时间不停地运转)。关键是B车间在生产的过程中,有可能要等待A车间的初加工产品。很显然所安排的第一个产品在A车间加工时,B车间是要等待的,最后一个产品在B车间加工时,A车间已经完成了任务。
要使总的空闲时间最少:
(1)就要把在A车间加工时间最短的部件优先加工,这样使得B车间能以最快的速度开始加工;
(2)把放在B车间加工时间最短的产品放在最后加工,这样使得最后A车间的空闲时间最少。
-
更严格的证明在这:本题贪心策略正确性证明
AC代码:
#include<cstdio> #include<algorithm> using namespace std; const int N=1e3+10; struct node{ int o;//工作编号 int t;//时间 int ab;//在哪个机器 bool operator < (const node &x) const{ return t<x.t;//排序(按t由小到大) } node(int _o=0,int _t=0,int _ab=0):o(_o),t(_t),ab(_ab){} }job[N]; int n,a[N],b[N],ti[N],ans[N]; void Johnson(){ for(int i=1;i<=n;i++){ if(a[i]<b[i]) job[i]=node(i,a[i],0); else job[i]=node(i,b[i],1); } sort(job+1,job+n+1); int l=0,r=n+1; for(int i=1;i<=n;i++){//生成最优解 if(!job[i].ab) ans[++l]=job[i].o; else ans[--r]=job[i].o; } } int main(){ scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d",a+i); for(int i=1;i<=n;i++) scanf("%d",b+i); Johnson();//生成最优解 for(int i=1;i<=n;i++) ti[i]=ti[i-1]+a[ans[i]];//计算最少时间 int sum=ti[1]+b[ans[1]]; for(int i=2;i<=n;i++) sum=max(sum,ti[i])+b[ans[i]]; printf("%d",sum); return 0; }