NC25043 [USACO 2007 Jan S]Protecting the Flowers

题目

题目描述

Farmer John went to cut some wood and left \(N (2 ≤ N ≤ 100,000)\) 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 \(T_i\) minutes \((1 ≤ T_i ≤ 2,000,000)\) away from its own barn. Furthermore, while waiting for transport, she destroys \(D_i (1 ≤ D_i ≤ 100)\) 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 × T_i\) minutes (\(T_i\) to get there and \(T_i\) 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, \(T_i\) and \(D_i\) , 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

题解

知识点:贪心,数学,排序。

注意到,交换某两头牛运送顺序,不改变其他结果。只要使任意两头牛的排序产生的毁坏最小,那么总毁坏将会是最小的,可以证明这是一个偏序关系,因此可以利用相邻两头牛的排序,来得到排序公式。

\(p_1,p_2\) 为相邻两牛毁坏的花, \(p_1',p_2'\) 为两牛逆序后毁坏的花,且 \(p_1+p_2 \leq p_1'+p_2'\)

设之前所有牛的运送时间和为 \(\Sigma\)

所以有

\[p_1 = 2\Sigma \cdot D_1,p_2 = 2(\Sigma+T_1) \cdot D_2\\ p_1' = 2\Sigma \cdot D_2,p_2' = 2(\Sigma+T_2) \cdot D_1\\ \]

显然有,\(p_1 \leq p_2'\)\(p_1' \leq p_2\) 。为了使 \(p_1+p_2 \leq p_1'+p_2'\) ,那么

\[2\Sigma \cdot D_1+2(\Sigma+T_1) \cdot D_2 \leq 2\Sigma \cdot D_2 + 2(\Sigma+T_2) \cdot D_1\\ 2\Sigma \cdot (D_1+D_2)+2T_1D_2 \leq 2\Sigma \cdot (D_1+D_2)+2T_2D_1\\ T_1D_2 \leq T_2D_1 \]

因此按此排序,最后序列的毁坏最小。

时间复杂度 \(O(n \log n)\)

空间复杂度 \(O(n)\)

代码

#include <bits/stdc++.h>

using namespace std;

struct pk {
    int t, d;
}p[100007];

int main() {
    std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
    int n;
    cin >> n;
    for (int i = 0;i < n;i++) {
        cin >> p[i].t >> p[i].d;
    }
    sort(p, p + n, [&](pk a, pk b) {return a.t * b.d < b.t *a.d;});
    long long sum = 0, time = 0;
    for (int i = 0;i < n;i++) {
        sum += time * p[i].d;
        time += 2 * p[i].t;
    }
    cout << sum << '\n';
    return 0;
}
posted @ 2022-06-16 21:58  空白菌  阅读(47)  评论(1编辑  收藏  举报