题面
【问题描述】
有 n 位同学同时找老师答疑。每位同学都预先估计了自己答疑的时间。 老师可以安排答疑的顺序,同学们要依次进入老师办公室答疑。 一位同学答疑的过程如下:
- 首先进入办公室,编号为 的同学需要 毫秒的时间。
- 然后同学问问题老师解答,编号为 的同学需要 毫秒的时间。
- 答疑完成后,同学很高兴,会在课程群里面发一条消息,需要的时间可 以忽略。
- 最后同学收拾东西离开办公室,需要 毫秒的时间。一般需要 10 秒、 20 秒或 30 秒,即 取值为 10000,20000 或 30000。
一位同学离开办公室后,紧接着下一位同学就可以进入办公室了。
答疑从 0 时刻开始。老师想合理的安排答疑的顺序,使得同学们在课程群 里面发消息的时刻之和最小。
【输入格式】
输入第一行包含一个整数 ,表示同学的数量。
接下来 行,描述每位同学的时间。其中第 行包含三个整数 , , ,意义如上所述。
【输出格式】
输出一个整数,表示同学们在课程群里面发消息的时刻之和最小是多少。
【样例输入】
3
10000 10000 10000
20000 50000 20000
30000 20000 30000
【样例输出】
280000
【样例说明】
按照 1, 3, 2 的顺序答疑,发消息的时间分别是 20000, 80000, 180000。
【评测用例规模与约定】
对于 30% 的评测用例,。
对于 60% 的评测用例,。
对于所有评测用例,,即 一定是 10000、20000、30000 之一。
思路
AC思路:贪心。
证明:
对于两个相邻的同学 i
和 i + 1
,假设前面同学答疑完毕已经消耗了 t
毫秒的时间。
第i
个同学答疑成功发消息的时刻为 , 答疑后离开办公室的时间为 。
而接下来的同学 i + 1
,答疑完成发消息的时刻为 ,答疑完成离开办公室的时间为 。
则可以得知,这两位同学发消息的时间总和为
都完成答疑后的时间为
考虑交换这两位同学的顺序。
则有第i+1
个同学答疑成功发消息的时刻为 , 答疑后离开办公室的时间为 。
而接下来的同学 i
,答疑完成发消息的时刻为 ,答疑完成离开办公室的时间为 。
则可以得知,这两位同学发消息的时间总和为
都完成答疑后的时间为
综上所述,交换两个相邻位置的同学,其完成答疑后的时间不会改变,但不同顺序进行答疑,前后相差
当 则说明交换 i
同学和 i+1
同学交换后的发消息时间减少了,先安排 i+1
同学再 i
同学比较好。反之,则交换后发消息的时间增多了或者没有变化,则不交换按照原顺序即可。证毕。
显然,比较两个同学是否交换即观察其三个属性之和 的大小关系。
代码
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long LL;
const int N = 1005;
int n;
struct Stu {
int s, a, e;
bool operator<(Stu &b) {
int s1 = s + a + e;
int s2 = b.s + b.a + b.e;
return s1 < s2;
}
} stu[N];
//贪心
int main() {
while (~scanf("%d", &n)) {
LL res = 0, t = 0;
for (int i = 0; i < n; i++) {
scanf("%d%d%d", &stu[i].s, &stu[i].a, &stu[i].e);
}
sort(stu, stu + n);
for (int i = 0; i < n; i++) {
res += t + stu[i].s + stu[i].a;
t += stu[i].s + stu[i].a + stu[i].e;
}
printf("%lld\n", res);
}
return 0;
}
标题: | 2020第十一届蓝桥杯国赛-H答疑 |
---|---|
链接: | https://www.fightingok.cn/detail/111 |
更新: | 2022-09-18 22:39:46 |
版权: | 本文采用 CC BY-NC-SA 3.0 CN 协议进行许可 |