【贪心之临项交换】P8732 [蓝桥杯 2020 国 ABC]|普及

本文涉及知识点

C++贪心 临项交换

P8732 蓝桥杯 2020 国 ABC

题目描述

有 n n n 位同学同时找老师答疑。每位同学都预先估计了自己答疑的时间。老师可以安排答疑的顺序,同学们要依次进入老师办公室答疑。

一位同学答疑的过程如下:

  1. 首先进入办公室,编号为 i i i 的同学需要 s i s_{i} si 毫秒的时间。

  2. 然后同学问问题老师解答,编号为 i i i 的同学需要 a i a_{i} ai 毫秒的时间。

  3. 答疑完成后,同学很高兴,会在课程群里面发一条消息,需要的时间可以忽略。

  4. 最后同学收拾东西离开办公室,需要 e i e_{i} ei 毫秒的时间。一般需要 10 10 10 秒、 20 20 20 秒或 30 30 30 秒,即 e i e_{i} ei 取值为 10000 10000 10000、 20000 20000 20000 或 30000 30000 30000。

一位同学离开办公室后,紧接着下一位同学就可以进入办公室了。

答疑从 0 0 0 时刻开始。老师想合理的安排答疑的顺序,使得同学们在课程群里面发消息的时刻之和最小。

输入格式

输入第一行包含一个整数 n n n,表示同学的数量。

接下来 n n n 行, 描述每位同学的时间。其中第 i i i 行包含三个整数 s i , a i , e i s_{i}, a_{i}, e_{i} si,ai,ei,意义如上所述。

输出格式

输出一个整数,表示同学们在课程群里面发消息的时刻之和最小是多少。

样例 #1

样例输入 #1

复制代码
3
10000 10000 10000
20000 50000 20000
30000 20000 30000

样例输出 #1

复制代码
280000

提示

【样例说明】

按照 1 , 3 , 2 1,3,2 1,3,2 的顺序答疑,发消息的时间分别是 20000 , 80000 , 180000 20000,80000,180000 20000,80000,180000 。

【评测用例规模与约定】

对于 30 % 30 \% 30% 的评测用例, 1 ≤ n ≤ 20 1 \leq n \leq 20 1≤n≤20 。

对于 60 % 60 \% 60% 的评测用例, 1 ≤ n ≤ 200 1 \leq n \leq 200 1≤n≤200 。

对于所有评测用例, 1 ≤ n ≤ 1000 , 1 ≤ s i ≤ 60000 , 1 ≤ a i ≤ 1000000 1 \leq n \leq 1000,1 \leq s_{i} \leq 60000,1 \leq a_{i} \leq 1000000 1≤n≤1000,1≤si≤60000,1≤ai≤1000000, e i ∈ { 10000 , 20000 , 30000 } e_{i} \in\{10000,20000,30000\} ei∈{10000,20000,30000} ,即 e i e_{i} ei 一定是 10000 、 20000 、 30000 10000 、 20000 、 30000 10000、20000、30000 之一。

蓝桥杯 2020 年国赛 A 组 H 题(B 组 H 题, C 组 J 题)。

贪心之临项交换

某个方案,第i个学生后面是第j个学生。令第i个学生四项目操作的时间分别是a,b,0,c;令第j个学生四项操作的时间分别是d,e,0,f。交换i,j,对其他学生无影响,故只考第i个和第j个学生的影响。

交换前:a+b+(a+b+c)+d+e

交换后:d+e+(d +e +f )+a+b

交换后减交换前:x = d+e+f -(a+b+c) 如果x <0,值得交换,即d+e+f < a+b+c。d+e+f小的在前,即升序。

代码

核心代码

cpp 复制代码
class Solution {
public:
	long long MinMS(vector<tuple<int, int, int>>& times) {
		sort(times.begin(), times.end(), [&](const tuple<int, int, int>& t1, const tuple<int, int, int>& t2) {
			return get<0>(t1) + get<1>(t1) + get<2>(t1) < get<0>(t2) + get<1>(t2) + get<2>(t2);
			});
		long long ans = 0, cur = 0;
		for (const auto& [a, b, c] : times) {
			cur += (a + b);
			ans += cur;
			cur += c;
		}
		return ans;
	}

};

int main() {
	//freopen("a.in", "r", stdin);
	int n,m;
	scanf("%d", &n);
	vector<tuple<int,int,int>> times;	
	for (int i = 0; i < n; i++) {
		tuple<int, int, int> t;
		int d1, d2, d3;
		scanf("%d%d%d", &d1,&d2,&d3);
		times.emplace_back(d1, d2, d3);
	}	
	auto res = Solution().MinMS(times);
	printf("%lld\n", res);
	return 0;
}

单元测试

cpp 复制代码
	TEST_METHOD(TestMethod11)
		{
			vector<tuple<int, int, int>> times = { {10000, 10000, 10000},{20000 ,50000 ,20000},{30000 ,20000, 30000} };	
			auto res = Solution().MinMS(times);
			AssertEx(280000LL, res);
		}

扩展阅读

我想对大家说的话
工作中遇到的问题,可以按类别查阅鄙人的算法文章,请点击《算法与数据汇总》。
学习算法:按章节学习《喜缺全书算法册》,大量的题目和测试用例,打包下载。重视操作
有效学习:明确的目标 及时的反馈 拉伸区(难度合适) 专注
闻缺陷则喜(喜缺)是一个美好的愿望,早发现问题,早修改问题,给老板节约钱。
子墨子言之:事无终始,无务多业。也就是我们常说的专业的人做专业的事。
如果程序是一条龙,那算法就是他的是睛
失败+反思=成功 成功+反思=成功

视频课程

先学简单的课程,请移步CSDN学院,听白银讲师(也就是鄙人)的讲解。
https://edu.csdn.net/course/detail/38771

如何你想快速形成战斗了,为老板分忧,请学习C#入职培训、C++入职培训等课程
https://edu.csdn.net/lecturer/6176

测试环境

操作系统:win7 开发环境: VS2019 C++17

或者 操作系统:win10 开发环境: VS2022 C++17

如无特殊说明,本算法用**C++**实现。

相关推荐
weixin_424183615 小时前
开放—封闭原则实战(下):基于策略的流程编排与编译期多态
c++·分布式·系统架构
wuminyu6 小时前
C++协程实现接收端的零拷贝Buffer管理原理剖析
java·linux·c语言·jvm·c++
小蒋学算法6 小时前
算法-交替删除操作后最后剩下的整数-跟着灵茶山艾府学算法
数据结构·算法
m0_380743876 小时前
C++中的freopen的用法实例详解
开发语言·c++
荆棘鸟智能6 小时前
林业遥感长势评估怎么做?从NDVI时序分析到LiDAR蓄积量回归
人工智能·算法·智慧林业
jimy17 小时前
polymorph.cpp里面的“析构函数、智能指针”问题
开发语言·c++
hhb_6187 小时前
AIRAGDebug:一键定位RAG链路异常
人工智能·python·算法
朝朝辞暮i7 小时前
C++ 第 6 课:switch —— 多状态选择
开发语言·c++·算法
朝朝辞暮i8 小时前
C++ 第 4 课:if / else —— 让程序自己做决定
开发语言·c++
苏打豆8 小时前
Pinocchio源码阅读——刚体运动物理量空间变换及求导
c++·线性代数·算法·矩阵·机器人