洛谷P1248 加工生产调度
流水作业调度问题
有\(N\)个作业要在两台机器\(M_1\)和\(M_2\)组成的流水线上完成加工。每个作业\(i\)都必须先花时间\(a_i\)在\(M_1\)上加工,然后花时间\(b_i\)在\(M_2\)上加工。
确定\(N\)个作业的加工顺序,使得从作业1在机器\(M_1\)上加工开始到作业\(N\)在机器\(M_2\)上加工完为止所用的总时间最短。
【算法】
直观上,最优调度一定让\(M_1\)没有空闲,\(M_2\)的空闲时间尽量短。
Johnson算法:设\(N_1\)为\(a<b\)的作业集合,\(N_2\)为\(≥b\)的作业集合,将\(N\)的作业按\(a\)非减序排序,\(N_2\)中的作业按照\(b\)非增序排序,则\(N_1\)作业接\(N_2\)作业构成最优顺序。
算法的程序易于实现,时间复杂度为\(O(nlogn)\),正确性需要证明。
P1248 加工生产调度
【问题描述】
某工厂收到了\(N\)个产品的订单,这\(N\)个产品分别在\(a\)、\(b\)两个车间加工,并且必须先在\(a\)加工后才可以送到\(b\)车间加工。
某个产品\(i\)在\(a\)、\(b\)两车间加工的时间分别为\(a_i\)、\(b_i\)。怎样安排这\(N\)个产品的加工顺序,才能总的加工时间最短?
这里所说的加工时间是指:从开始加工第一个产品到所有的产品都已在两车间加工完毕的时间。
【输入格式】
第一行仅一个数据\(N\)(0<\(N\)<1000),表示产品的数量。
接下来\(N\)个数据是表示这\(N\)个产品在\(a\)车间加工,各自所要的时间(都是整数)。最后的\(N\)个数据是表示这\(N\)个产品在\(b\)车间加工,各自所要的时间(都是整数)
【输出格式】
第一行一个数据,表示最短的加工时间。
第二行是一种用时最短的产品加工顺序。
【样例输入】
5
3 5 8 7 10
6 2 1 4 9
【样例输出】
34
1 5 4 2 3
【思路】
求一个加工顺序使得加工总用时最短,就是让机器的空闲时间最短。一旦\(a\)机器开始加工,则\(a\)机器将会不停地进行作业,关键是\(b\)机器在加工过程中有可能要等待\(a\)机器。很明显第一个部件在\(a\)机器上加工时,\(b\)机器必须等待,最后一个部件在\(b\)机器上加工时,\(a\)机器也在等待\(b\)机器的完工。
可以大胆猜想,要使机器总的空闲时间最短就要把在\(a\)机器上加工时间最短的部件最先加工,这样使得\(b\)机器能在最短的空闲时间内开始加工;把在\(b\)机器上加工时间最短的部件放在最后加工,这样使得\(a\)机器用最短时间等待\(b\)机器完工。
于是我们可以设计出这样的贪心策略:设\(M_i=min{a_i,b_i},\)将\(M\)按照从小到大的顺序排序,然后从第1个开始处理,若\(M_i=a_i\),则将它排在从头开始的作业后面,若\(M_i=b_i\),则将它排在从尾开始的作业前面。
例如:
\(N\)=5,
\((a_1,a_2,a_3,a_4,a_5)=(3,5,8,7,10)\),
\((b_1,b_2,b_3,b_4,b_5)=(6,2,1,4,9)\),
则\((M_1,M_2,M_3,M_4,M_5)=(3,2,1,4,9)\),
排序之后为\((M_3,M_2,M_1,M_4,M_5)\)。
处理\(M_3\): ∵ \(M_3=b_3\),∴\(M_3\)排在后面;加入\(M_3\)之后的加工顺序为\((,,,,3)\);
处理\(M_2\): ∵ \(M_2=b_2\),∴\(M_2\)排在后面;加入\(M_2\)之后的加工顺序为\((,,,2,3)\);
处理\(M_1\): ∵ \(M_1=a_1\),∴\(M_1\)排在前面;加入\(M_1\)之后的加工顺序为\((1,,,2,3)\);
处理\(M_4\): ∵ \(M_4=b_4\),∴\(M_4\)排在后面;加入\(M_4\)之后的加工顺序为\((1,,4,2,3)\);
处理\(M_5\): ∵ \(M_5=b_5\),∴\(M_5\)排在后面;加入\(M_5\)之后的加工顺序为\((1,5,4,2,3)\);
则最优加工顺序就是\((1,5,4,2,3)\),最短时间为34。
显然这个结果是最优解。
问题是这种贪心策略是否正确呢?还需证明。
【证明】
去年刚学OI时写的(萌新刚学OI),字写得渣。
Code
#include<bits/stdc++.h>
using namespace std;
const int N = 2005;
struct data {
int id,a,b;
} J[N], ans[N];
int n;
inline bool cmp(const data &A, const data &B) {//Jhonson不等式排序
return min(A.a, A.b) < min(B.a, B.b);
}
int main() {
scanf("%d", &n);
for(int i = 1; i <= n; ++i) {
scanf("%d", &J[i].a);
J[i].id = i;//原数组下标
}
for(int i = 1; i <= n; ++i) scanf("%d", &J[i].b);
sort(J + 1, J + 1 + n, cmp);
for(int i = 1, p = 1, q = n; i <= n; ++i) {//p--队头 q--队尾
if(J[i].a <= J[i].b) ans[p++] = J[i];
else ans[q--] = J[i];
}
int time1 = 0, time2 = 0;//time1--A机器上加工用时 time2--B机器上加工用时
for(int i = 1; i <= n; ++i) {
time1 += ans[i].a;//第i件产品在A机器上所用时间
time2 = max(time1, time2);//在A机器上加工完才能到B机器 未加工完需要等待
time2 += ans[i].b;//第i件产品在B机器上所用时间
}
printf("%d\n", time2);//最后一件在B机器加工完的时刻为结束时刻
for(int i = 1; i <= n; ++i) printf("%d ", ans[i].id);//输出方案
return 0;
}
洛谷P1248 加工生产调度的更多相关文章
- 洛谷P1248 加工生产调度 贪心
正解:贪心 解题报告: 传送门$QwQ$ $umm$直接看可能比较难想,可以先考虑另一个题? 有$n$个小怪,每打一只小怪会扣$a_i$的血,打完之后会回升$b_i$的血,问至少要多少血量才能使全程血 ...
- 【流水调度问题】【邻项交换对比】【Johnson法则】洛谷P1080国王游戏/P1248加工生产调度/P2123皇后游戏/P1541爬山
前提说明,因为我比较菜,关于理论性的证明大部分是搬来其他大佬的,相应地方有注明. 我自己写的部分换颜色来便于区分. 邻项交换对比是求一定条件下的最优排序的思想(个人理解).这部分最近做了一些题,就一起 ...
- 【题解/模板】P1248 加工生产调度(贪心)
[题解/模板]P1248 加工生产调度(贪心) 分析: \(A\)流水线的时间是确定的,所以现在就是要让\(b\)的时间尽量短 \(tB > tA\),除非所有东西都不需要\(b\).(t指结束 ...
- 洛谷 P5663 加工零件
题目传送门 解题思路: 最暴力的做法: bfs模拟,每次将一个阶段的所有点拿出来,将其所有直连的点都放进队列,知道本阶段结束,最后看1号点会不会在最后一个阶段被放入队列.(洛谷数据40分) 优化了一下 ...
- 【洛谷P1248】加工生产调度
题目大意:某工厂收到了n个产品的订单,这n个产品分别在A.B两个车间加工,并且必须先在A车间加工后才可以到B车间加工.某个产品i在A.B两车间加工的时间分别为Ai.Bi.怎样安排这n个产品的加工顺序, ...
- Luogu [P1248] 加工生产调度
题目链接 这个题可以贪心 我们首先想:对于所有产品,我们大致可以将其分为三类: ①.在A车间的时间要比B车间长. ②.两者一样. ③.在B车间的时间要比A车间长. 对于这三大类,怎么安排顺序? 可以看 ...
- 洛谷 P5663 加工零件 & [NOIP2019普及组] (奇偶最短路)
传送门 解题思路 很容易想到用最短路来解决这一道问题(题解法),因为两个点之间可以互相无限走,所以如果到某个点的最短路是x,那么x+2,x+4也一定能够达到. 但是如何保证这是正确的呢?比如说到某个点 ...
- 「一本通 1.1 例 4」加工生产调度(贪心算法)(luogu P1248)题解
加工生产调度 题目描述 某工厂收到了 n n n 个产品的订单,这 n n n 个产品分别在 A.B 两个车间加工,并且必须先在 A 车间加工后才可以到 B 车间加工. 某个产品 i i i 在 A. ...
- 洛谷P3655 差分数组 树状数组
题目链接:https://www.luogu.org/problemnew/show/P3655 不一定对,仅供参考,不喜勿喷,不喜勿喷. 先copy洛谷P3368 [模板]树状数组 2 题解里面一位 ...
随机推荐
- HBase 面向列的存储
- 解决IDEA maven多模块打包问题
参考: https://www.jianshu.com/p/37c6688c4fcb https://blog.csdn.net/sjhuangx/article/details/71519066 h ...
- 附录C 准备NCDC气象数据(加解释)
附录C 准备NCDC气象数据 这里首先简要介绍如何准备原始气象数据文件,以便我们能用Hadoop对它们进行分析.如果打算得到一份数据副本供Hadoop处理,可按照本书配套网站(网址为http://ww ...
- Leetcode942. DI String Match增减字符串
给定只含 "I"(增大)或 "D"(减小)的字符串 S ,令 N = S.length. 返回 [0, 1, ..., N] 的任意排列 A 使得对于所有 i ...
- Windows API 第四篇 文件操作
创建或打开文件(也可用于打开管道,油槽,硬件设备等): HANDLE CreateFile( LPCTSTR lpFileName, // file name DWORD dwDesiredAcces ...
- mac版pycharm的字体和行间距设置
- SQL Server数据库存储过程的异常处理
SQL Server数据库存储过程的异常处理是非常重要的,明确的异常提示能够帮助我们快速地找到问题的根源,节省很多时间.本文我们就以一个插入数据为例来说明SQL Server中的存储过程怎么捕获异常的 ...
- Ajax和json一道基本的练习题
关于ajax是javaEE中最基本的操作: 下面是这道题: 基本功能: jsp+servlet+ajax实现用户信息查询,实现无刷新删除 用户信息包括 学号 姓名 出生日期 性别 操作 2017010 ...
- docker启动单节点server模式的consul | Bitdoom
原文:docker启动单节点server模式的consul | Bitdoom docker启动单节点server模式的consul 2017-09-07 环境:MacOSX, consul_0.9. ...
- 2019-2-19-win10-uwp-客户端如何发送类到-asp-dotnet-core-作为参数
title author date CreateTime categories win10 uwp 客户端如何发送类到 asp dotnet core 作为参数 lindexi 2019-2-19 9 ...