LibreOJ #10003加工生产调度(Johnson算法求解最短时间)

题目链接https://loj.ac/problem/10003
在这里插入图片描述
样例输入

5
3 5 8 7 10
6 2 1 4 9

样例输出

34
1 5 4 2 3

Johnson算法流程:
N 1 N_1 N1为a<b的作业集合, N 2 N_2 N2为a>=b的作业集合,将 N 1 N_1 N1的作业按a递增排序; N 2 N_2 N2的作业按b递减排序, N 1 N_1 N1作业接 N 2 N_2 N2作业构成最优顺序。

思维的直观性:
一旦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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zaiyang遇见

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值