题目描述

Farmer John went to cut some wood and left cows eating the grass, as usual. When he returned, he found to his horror that the cluster of cows was in his garden eating his beautiful flowers. Wanting to minimize the subsequent damage, FJ decided to take immediate action and transport each cow back to its own barn.
Each cow i is at a location that is minutes away from its own barn. Furthermore, while waiting for transport, she destroys flowers per minute. No matter how hard he tries, FJ can only transport one cow at a time back to her barn. Moving cow i to its barn requires 2 × Ti minutes (Ti to get there and Ti to return). FJ starts at the flower patch, transports the cow to its barn, and then walks back to the flowers, taking no extra time to get to the next cow that needs transport.
Write a program to determine the order in which FJ should pick up the cows so that the total number of flowers destroyed is minimized.

输入描述:

Line 1: A single integer N
Lines 2..N+1: Each line contains two space-separated integers, and , that describe a single cow's characteristics

输出描述:

Line 1: A single integer that is the minimum number of destroyed flowers

示例1

输入
6
3 1
2 5
2 3
3 2
4 1
1 6
输出
86

解答

【样例解释】
约翰用6,2,3,4,1,5的顺序来运送他的奶牛
这题做的时候是hzwer神犇出的模考题,然后错得一塌糊涂qwq
分析:
这题用贪心来做。
单独看牛群中的两头牛a、b,每头牛拥有两个参数D和T。
假设这两头牛是相邻的,a在b之后被带走,考虑将这两头牛交换顺序,不会影响牛群中其他牛吃花的时间。
交换顺序前 吃花数量:
交换顺序后 吃花数量:
要使这次交换顺序是有效的,也就是说交换后的吃花数量减少了
则应满足
化简可得 
推理可知,当一头牛的【吃花数量/带走时间】越大时,它应该先被带走。
简单理解的话也可以认为是先把腿长而且能吃的奶牛带走吧...(逃)
AC代码:
#include<iostream>
  #include<cstdio>
   #include<algorithm>
   #include<cstring>
  #include<queue>
  
   using namespace std;
  const int MAXN = 100005;
  
  struct cow
  {
      int t,d;
      double jud;
 }a[MAXN];//存储奶牛的相关参数 
 
  long long sum[MAXN];
 
  bool cmp(cow a,cow b)
  {
      return a.jud > b.jud?1:0;
 }//根据比值来比较结构体大小 
  
  int main()
   {
     int n;
      scanf("%d",&n);
      for(int i = 0;i < n;++ i)
      {
          scanf("%d%d",&a[i].t,&a[i].d);
          a[i].jud = (double) a[i].d/a[i].t;
      }
      sort(a,a+n,cmp);
      
      sum[n-1] = (long long)a[n-1].d;
     for(int i = n-1;i >= 0;i --)
          sum[i] = (long long)a[i].d + sum[i+1];
      //计算剩余的i头奶牛每分钟吃掉的花朵 
      long long ans = 0;
      for(int i = 0;i < n;i ++)
      {
          ans += (long long)2 * a[i].t * sum[i+1];
      }
     printf("%lld",ans);
      return 0;
  }

来源:嘒彼小星