csp信奥赛C++高频考点专项训练之贪心算法 --【排序贪心】:加工生产调度

csp信奥赛C++高频考点专项训练之贪心算法 --【排序贪心】:加工生产调度

题目描述

某工厂收到了 n n n 个产品的订单,这 n n n 个产品分别在 A、B 两个车间加工,并且必须先在 A 车间加工后才可以到 B 车间加工。一个车间在同一时刻只能加工一个产品。

某个产品 i i i 在 A、B 两车间加工的时间分别为 A i , B i A_i,B_i Ai,Bi。怎样安排这 n n n 个产品的加工顺序,才能使总的加工时间最短。

这里所说的加工时间是指:从开始加工第一个产品到最后所有的产品都已在 A、B 两车间加工完毕的时间。

输入格式

第一行仅---个整数 n n n,表示产品的数量。

接下来一行 n n n 个整数是表示这 n n n 个产品在 A 车间加工各自所要的时间。

最后的 n n n 个整数是表示这 n n n 个产品在 B 车间加工各自所要的时间。

输出格式

第一行一个整数,表示最少的加工时间。

第二行是一种最小加工时间的加工顺序。

输入输出样例 1
输入 1
复制代码
5
3 5 8 7 10
6 2 1 4 9
输出 1
复制代码
34
1 5 4 2 3
说明/提示

1 ≤ n ≤ 1000 1\leq n\leq 1000 1≤n≤1000, 1 ≤ A i , B i ≤ 1000 1\leq A_i,B_i\leq 1000 1≤Ai,Bi≤1000。

分析思路

这是一个双机流水作业调度问题,目标是求最小化总加工时间。
Johnson 规则给出了最优解:

  1. 将作业分为两组:
    • 第一组 N 1 N_1 N1:满足 A i ≤ B i A_i \le B_i Ai≤Bi 的作业,按 A i A_i Ai 升序排列。
    • 第二组 N 2 N_2 N2:满足 A i > B i A_i > B_i Ai>Bi 的作业,按 B i B_i Bi 降序排列。
  2. 最优加工顺序为 N 1 N_1 N1 在前, N 2 N_2 N2 在后。
  3. 按此顺序模拟加工:设 t A t_A tA 为 A 车间完成当前作业的时刻, t B t_B tB 为 B 车间完成当前作业的时刻。
    对于每个作业 i:
    • t A ← t A + A i t_A \leftarrow t_A + A_i tA←tA+Ai
    • t B ← max ⁡ ( t B , t A ) + B i t_B \leftarrow \max(t_B, t_A) + B_i tB←max(tB,tA)+Bi
      最终 t B t_B tB 即为最短加工时间。

正确性:基于交换论证,任何不满足 Johnson 规则的相邻作业对都可以通过交换优化总时间,因此该规则得到全局最优。

代码实现

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;

struct nd{int id,a,b;};//产品:编号,A时间,B时间
int n,a[1005],b[1005];
vector<nd> v1,v2;//两组:A<=B 和 A>B

bool cmp1(nd x,nd y){return x.a<y.a;}//第一组按A升序
bool cmp2(nd x,nd y){return x.b>y.b;}//第二组按B降序

int main(){
    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++){
        if(a[i]<=b[i]) v1.push_back({i,a[i],b[i]});
        else v2.push_back({i,a[i],b[i]});
    }
    sort(v1.begin(),v1.end(),cmp1);//第一组升序
    sort(v2.begin(),v2.end(),cmp2);//第二组降序
    vector<int> ord;//最终顺序
    for(auto &p:v1){ord.push_back(p.id);}
    for(auto &p:v2){ord.push_back(p.id);}
    int ta=0,tb=0;
    for(int i=0;i<ord.size();i++){
        int id=ord[i];
        ta+=a[id];//A车间加工
        tb=max(tb,ta)+b[id];//B车间加工(需等待A完成)
    }
    cout<<tb<<endl;//输出最少时间
    for(int i=0;i<ord.size();i++){
        if(i)cout<<' ';
        cout<<ord[i];
    }
    cout<<endl;
    return 0;
}

功能分析

  1. 输入处理:读取产品数量 n,分别读取 A、B 车间的加工时间数组。
  2. 分组与排序
    • 遍历每个产品,若 A i ≤ B i A_i \le B_i Ai≤Bi 则放入 v1,否则放入 v2
    • v1 按 A i A_i Ai 升序排序(cmp1)。
    • v2 按 B i B_i Bi 降序排序(cmp2)。
  3. 构造最优顺序 :将 v1v2 中的产品编号依次存入 ord 向量,即 Johnson 规则确定的最优加工顺序。
  4. 计算最短加工时间
    • 初始化 A 车间结束时间 ta=0,B 车间结束时间 tb=0
    • 按最优顺序模拟:每个产品先在 A 加工(ta += a[id]),然后立即在 B 加工,但 B 必须等待 A 完成且自身空闲,故 tb = max(tb, ta) + b[id]
    • 循环结束后 tb 即为总加工时间。
  5. 输出结果:第一行输出最短时间,第二行输出最优加工顺序(编号用空格分隔)。

各种学习资料,助力大家一站式学习和提升!!!

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
int main(){
	cout<<"##########  一站式掌握信奥赛知识!  ##########";
	cout<<"#############  冲刺信奥赛拿奖!  #############";
	cout<<"######  课程购买后永久学习,不受限制!   ######";
	return 0;
}

【秘籍汇总】(完整csp信奥赛C++学习资料):

1、csp/信奥赛C++,完整信奥赛系列课程(永久学习):

https://edu.csdn.net/lecturer/7901 点击跳转

2、CSP信奥赛C++竞赛拿奖视频课:

https://edu.csdn.net/course/detail/40437 点击跳转

https://edu.csdn.net/course/detail/41081 点击跳转

3、csp信奥赛高频考点知识详解及案例实践:

CSP信奥赛C++动态规划:
https://blog.csdn.net/weixin_66461496/category_13096895.html点击跳转

CSP信奥赛C++标准模板库STL:
https://blog.csdn.net/weixin_66461496/category_13108077.html 点击跳转

信奥赛C++提高组csp-s知识详解及案例实践:
https://blog.csdn.net/weixin_66461496/category_13113932.html 点击跳转

4、csp信奥赛冲刺一等奖有效刷题题解:

CSP信奥赛C++初赛及复赛高频考点真题解析(持续更新): https://blog.csdn.net/weixin_66461496/category_12808781.html 点击跳转

信奥赛C++提高组csp-s初赛&复赛真题题解(持续更新):
https://blog.csdn.net/weixin_66461496/category_13125089.html 点击跳转

5、GESP C++考级真题题解:

GESP(C++ 一级+二级+三级)真题题解(持续更新):https://blog.csdn.net/weixin_66461496/category_12858102.html 点击跳转

GESP(C++ 四级+五级+六级)真题题解(持续更新):https://blog.csdn.net/weixin_66461496/category_12869848.html 点击跳转

GESP(C++ 七级+八级)真题题解(持续更新):
https://blog.csdn.net/weixin_66461496/category_13117178.html 点击跳转

· 文末祝福 ·

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
int main(){
	cout<<"跟着王老师一起学习信奥赛C++";
	cout<<"    成就更好的自己!       ";
	cout<<"  csp信奥赛一等奖属于你!   ";
	return 0;
}
相关推荐
浅念-3 小时前
递归解题指南:LeetCode经典题全解析
数据结构·算法·leetcode·职场和发展·排序算法·深度优先·递归
Kiling_07043 小时前
Java集合进阶:Set与Collections详解
算法·哈希算法
智者知已应修善业4 小时前
【51单片机89C51及74LS273、74LS244组成】2022-5-28
c++·经验分享·笔记·算法·51单片机
洛水水4 小时前
【力扣100题】33.验证二叉搜索树
算法·leetcode·职场和发展
SimpleLearingAI4 小时前
聚类算法详解
算法·数据挖掘·聚类
刀法如飞5 小时前
Go 字符串查找的 20 种实现方式,用不同思路解决问题
算法·面试·程序员
Byron Loong7 小时前
【c++】为什么有了dll和.h,还需要包含lib
java·开发语言·c++
Dlrb12117 小时前
C语言-指针数组与数组指针
c语言·数据结构·算法·指针·数组指针·指针数组·二级指针
WL_Aurora7 小时前
Python 算法基础篇之集合
python·算法
坚果派·白晓明7 小时前
【鸿蒙PC三方库移植适配框架解读系列】第一篇:Lycium C/C++ 三方库适配 — 概述与环境配置
c语言·开发语言·c++·harmonyos·开源鸿蒙·三方库·c/c++三方库