加工生产调度(非常nice的贪心题!)

题目描述

某工厂收到了 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; 
}
  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

liaoxiyan123

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

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

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

打赏作者

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

抵扣说明:

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

余额充值