蓝桥杯刷题——答疑(贪心)

274 阅读1分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第1天,点击查看活动详情

这是蓝桥杯20年国赛的一道贪心题目,临近22年省赛的时候,在刷题赛中又出现了。

题目

image.png

image.png

思路

题目要求同学们在课程群中发消息的时刻之和最小。我们先将同学们进入办公室和问问题这两件时间所花的时候合在一起,设为s1。然后再是同学出门的所花的时间s2。很多人的第一想法可能是将s1越小的人排在前面。而事实上,这是不行的,假设现在只有两个人,s11=10s,s21=3s,s12=6s,s22=10s,第二个人s1所花时间,如果把他排在前面的话,所花的总时间是26s,而第一个人排在前面的花,所花的时间是19s。很明显s1越小的排在前面是行不通的。那么我们如何排列?我们应将s1和s2所花时间总和最低的人排在前列。当只有两个人的时候,第一个人s11+s21<第二个人s12+s22,发消息的时刻之和就为s11+s11+s21+s12,如果第二个人排第一位,那么总时刻为s12+s12+s22+s11,前者减后者等于s11+s21-s12-s22,为负,显而易见,第一个人就要排第一位,排出s1和s2所花总时间最低的人后,在剩下的人中接着排出s1和s2所花总时间最低的人。所有人排好序之后,这样在课程群中发消息的时刻之和肯定是最小的。

代码

#include <algorithm>
#include<iostream>
using namespace std;
struct NNum{
  int sum1;
  int sum2;
}; 
int n;
bool cmp(NNum a,NNum b){
  return a.sum2<=b.sum2;
}
int main()
{
  cin>>n;
  NNum Num[1001];
  for(int i=0;i<n;i++){
    int a,b,c;
    cin>>a>>b>>c;
    Num[i].sum1=c;
    Num[i].sum2=a+b+c;
  }
  sort(Num,Num+n,cmp);
  long long ant=0;
  for(int i=0;i<n;i++){
    ant+=Num[i].sum2*(n-i)-Num[i].sum1;
  }
  cout<<ant;
  return 0;
}

最终结果可以通过测试。