答疑

问题描述

有 n 位同学同时找老师答疑。每位同学都预先估计了自己答疑的时间。

老师可以安排答疑的顺序,同学们要依次进入老师办公室答疑。

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

  1. 首先进入办公室,编号为 i 的同学需要 s 毫秒的时间。
  2. 然后同学问问题老师解答,编号为 i 的同学需要 a 毫秒的时间。
  3. 答疑完成后,同学很高兴,会在课程群里面发一条消息,需要的时间可以忽略。
  4. 最后同学收拾东西离开办公室,需要 e 毫秒的时间。一般需要 10 秒、20 秒或 30 秒,即 e 取值为 10000 ,20000 或 30000 。

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

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

输入格式
输入第一行包含一个整数 n ,表示同学的数量。
接下来 n 行,描述每位同学的时间,其中第 i 行包含三个整数 s,a,e ,意义如上所述。

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

样例输入

3
10000 10000 10000
20000 50000 20000
30000 20000 30000

样例输出

280000

数据范围
对于 30% 的评测用例,1≤n≤20
对于 60% 的评测用例,1≤n≤200
对于所有评测用例,1 ≤ n ≤ 1000 , 1 ≤ s ≤ 60000 , 1 ≤ a ≤ 1000000 , e ∈ 10000 , 20000 , 30000 ,即 e 一定是 10000 、 20000 、 30000 之一。

贪心

这段代码是用来解决上述答疑问题的,旨在找到一种答疑顺序,使得同学们在群里发消息的时刻之和最小。下面是代码的详细注释,解释每一部分的作用:

#include<bits/stdc++.h> // 引入常用库文件,这是编程比赛中常用的简写方式
using namespace std;    // 使用标准命名空间
typedef long long ll;   // 定义长整型别名 ll,便于处理大整数

// 定义数组,对应 n 位同学的进入办公室时间、答疑时间和离开办公室时间
int si[1010],ai[1010],ei[1010];
// 定义数组 s 用来存储每位同学答疑的总时间(包括进入、答疑和离开时间)
ll s[1010];

int main()
{
    int n; // 定义变量 n 来存储同学的数量
    cin>>n; // 从标准输入读取同学的数量
    ll d=0; // 定义变量 d 用于记录初始的发消息的时刻之和
    
    // 循环读取每位同学的时间数据
    for(int i=0;i<n;i++)
    {
        cin>>si[i]>>ai[i]>>ei[i]; // 读取第 i 位同学的进入、答疑和离开时间
        s[i]=si[i]+ai[i]+ei[i];   // 计算每位同学的总答疑时间
        d+=si[i]+ai[i]; // 累加进入和答疑时间到 d,注意离开时间在这里不计入
    }
    
    // 使用 sort 函数对 s 数组进行排序,按照答疑的总时间从小到大排序
    sort(s,s+n);
    
    // sum 初始值为 d,即所有同学的进入和答疑时间之和
    ll sum=d;
    
    // 这个循环计算排序后的答疑时间对发消息时刻之和的影响
    int t=n; // 定义变量 t 为同学数量
    for(int i=0;i<n-1;i++)
    {
        sum+=(t-1)*s[i]; // 乘以 t-1 是因为每个 s[i] 会被后面的同学重复经历
        t--; // 每次循环后,影响的同学数减少一个
    }
    
    cout<<sum; // 输出计算出的同学们在课程群里面发消息时刻之和
    return 0; // 程序正常结束
}

这段代码实现了一个高效的算法,通过先累加所有同学的进入和答疑时间,然后排序并计算每个同学离开办公室的时间对后面同学发消息时刻的影响,最后得到一个最小化的发消息时刻之和。

04-30 23:07