NC25043 Protecting the Flower

题目

  • 原题地址:Protecting the Flower
  • 题目编号:NC25043
  • 题目类型:贪心、推公式
  • 时间限制:C/C++ 1秒,其他语言2秒
  • 空间限制:C/C++ 32768K,其他语言65536K

1.题目大意

  • 农场 \(n\) 头牛,都在吃花,农民 \(John\) 心碎了,要把牛搬回牛棚,问如何损失花最小(求最小值)
  • 搬运第 \(i\) 头牛到牛棚花费时间 \(t_i\)(往返则是 \(2t_i\)),每头牛每个单位时间吃花量为 \(d_i\)
  • 初始在牛的位置,从一头牛走到另一头牛的时间不计

2.题目分析

  • 有两个参数 \(t\)\(d\),我们只需要根据参数排好序再计算结果即可
  • 排序的依据为(先运 \(a\)):\(t_a*d_b<t_b*d_a\)
  • 主要有两种推导思路
  1. \(t_a*(d_b+Rd)+t_b*Rd<t_b*(d_a+Rd)+t_a*Rd\)
    从剩下的牛中选择两头 \(a\)\(b\) 进行排序,\(Rd\) 为剩下的所有牛(除了 \(a\)\(b\))的 \(d\) 之和
    上式的含义为先运牛 \(a\) 比先运牛 \(b\) 的剩余代价小(因为前面的代价相同)
    式中每一项都需要乘二(往返),所以直接约掉了,最后化简后可以得到排序的依据
  2. \(Dt*d_a+(Dt+2*t_a)*d_b<Dt*d_b+(Dt+2*t_b)*d_a\)
    从剩下的牛中选择两头 \(a\)\(b\) 进行排序,\(Dt\) 为前面搬运完的所有牛的 \(t\) 之和
    上式的含义为在先运牛 \(a\) 比先运牛 \(b\) 的代价小(包含从开始的两头牛的代价)
    也可以理解为在已经运完的牛的总代价基础上加上运牛 \(a\) 比加上运牛 \(b\) 的代价小(已经运完的代价相同,可以直接约掉)

3.题目代码

#include <bits/stdc++.h>

using namespace std;

typedef struct cow{
    int t;
    int d;
}cow;

bool cmp(cow a, cow b)
{
    return a.t * b.d < b.t * a.d;
}

int main() {
    int n;
    cin >> n;
    cow cc[n];
    long long sum = 0;
    long long ans = 0;
    for(int i=0;i<n;i++)
    {        
        cin >> cc[i].t >> cc[i].d;
        sum += cc[i].d;
    }    
    sort(cc, cc+n, cmp);
    for(int i=0;i<n-1;i++)
    {
        sum -= cc[i].d;
        ans += sum * cc[i].t * 2;
    }
    cout << ans << endl;
}
posted @ 2022-07-16 09:57  仪战群儒  阅读(24)  评论(0)    收藏  举报