题面
有\(n\) 位同学同时找老师答疑。每位同学都预先估计了自己答疑的时间。老师可以安排答疑的顺序,同学们要依次进入老师办公室答疑。
一位同学答疑的过程如下:
首先进入办公室,编号为 i 的同学需要 s_i 毫秒的时间。
然后同学问问题老师解答,编号为 i 的同学需要 a_i 毫秒的时间。
答疑完成后,同学很高兴,会在课程群里面发一条消息,需要的时间可以忽略。
最后同学收拾东西离开办公室,需要 e_i 毫秒的时间。一般需要 10秒、20秒或 30秒,即 e_i 取值为 10000、20000 或 30000。
一位同学离开办公室后,紧接着下一位同学就可以进入办公室了。
答疑从 0 时刻开始。老师想合理的安排答疑的顺序,使得同学们在课程群里面发消息的时刻之和最小。
分析
记 $ Sum[i] $为第 \(i\)个同学的答疑总时间,\(eSum\)为所有同学的\(e_i\)之和。
第\(1\)个人的发消息时刻为:
\[s[1]+a[1]=Sum[1]-e[1] \]第\(2\)个人的发消息时刻为:
\[Sum[1]+s[2]+a[2]=Sum[1]+Sum[2]-e[2] \]第\(n\)个人的发消息时刻为:
\[Sum[1]+...+Sum[n]-e[n] \]\(n\)个人的发消息时刻总和为:
\[\sum_{i=1}^n (n-i+1)Sum[i]-eSum \]考虑简单贪心,从小到大排序\(Sum[i]\)即可。
Code
#include<iostream>
#include<cstdio>
#include<algorithm>
const int maxn = 1e4 + 10;
#define ll long long
int n;
ll esum;
struct node {
int s, a, e;
ll sum;
bool operator<(const node &p) const {
return sum < p.sum;
}
} t[maxn];
int main() {
scanf("%d", &n);
for (int i = 1; i <= n; i++) {
scanf("%d%d%d", &t[i].s, &t[i].a, &t[i].e);
t[i].sum = t[i].s + t[i].a + t[i].e;
esum += t[i].e;
}
std::sort(t + 1, t + 1 + n);
ll ans = 0;
for (int i = 1; i <= n; i++)
ans += (n - i + 1) * t[i].sum;
ans -= esum;
printf("%lld", ans);
return 0;
}
标签:同学,ABC,ll,Sum,答疑,蓝桥,2020,时刻,发消息
From: https://www.cnblogs.com/MrWangnacl/p/16990048.html