LibreOJ #10003加工生产调度(Johnson算法求解最短时间)
程序员文章站
2023-12-25 12:24:27
...
题目链接:https://loj.ac/problem/10003
样例输入
5
3 5 8 7 10
6 2 1 4 9
样例输出
34
1 5 4 2 3
Johnson算法流程:
设为a<b的作业集合,为a>=b的作业集合,将的作业按a递增排序;的作业按b递减排序,作业接作业构成最优顺序。
思维的直观性:
一旦A机器开始加工,则A机器将会不停地进行作业,关键是B机器在加工过程中有可能要等待A机器。最明显的是:第一个部件在A机器上加工时,B机器必须等待;最后一个部件在B机器上加工时,A机器也必须等待B机器的完工。
所以:
A机器上加工时间最短的部件最先加工,这样使得B机器能在最短的空闲时间内开始加工;把在B机器上加工时间最短的部件放在最后加工,这样使得A机器用最短时间等待B机器完工。
完整代码:
#include<cstdio>
#include<cstring>
#include<math.h>
#include<stdlib.h>
#include<iostream>
#include<algorithm>
using namespace std;
const int N=1e3+10;
int a[N],b[N],m[N];
int s[N];///记录下标
int main()
{
int n;
cin>>n;
for(int i=1; i<=n; i++)
cin>>a[i];
for(int i=1; i<=n; i++)
cin>>b[i];
for(int i=1; i<=n; i++)
{
m[i]=min(a[i],b[i]);
s[i]=i;
}
for(int i=1; i<=n; i++) //m[]从小到大排序
{
for(int j=i+1; j<=n; j++)
{
if(m[i]>m[j])
{
swap(m[i],m[j]);
swap(s[i],s[j]);
}
}
}
int l=0,r=n+1;
int ans[N];
for(int i=1; i<=n; i++)
{
if(m[i]==a[s[i]])//a<b,从前到后
{
l++;
ans[l]=s[i];
}
else//a>=b,从后到前
{
r--;
ans[r]=s[i];
}
}
int x=0,y=0;///x为在A加工的时间,y为在B加工的时间
for(int i=1; i<=n; i++)
{
x+=a[ans[i]];
if(x>y)//A加工时B在等待,所以x大于y时,b加工的时间等于a
y=x;
y+=b[ans[i]];
}
cout<<y<<endl<<ans[1];
for(int i=2; i<=n; i++)
cout<<" "<<ans[i];
cout<<endl;
return 0;
}