欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

程序员文章站 2023-12-25 12:24:27
...

题目链接https://loj.ac/problem/10003
LibreOJ #10003加工生产调度(Johnson算法求解最短时间)
样例输入

5
3 5 8 7 10
6 2 1 4 9

样例输出

34
1 5 4 2 3

Johnson算法流程:
N1N_1为a<b的作业集合,N2N_2为a>=b的作业集合,将N1N_1的作业按a递增排序;N2N_2的作业按b递减排序,N1N_1作业接N2N_2作业构成最优顺序。

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

相关标签: 贪心2---实际应用

上一篇:

下一篇: