题解:洛谷 P2878 [USACO07JAN] Protecting the Flowers S

【题目来源】

洛谷:[P2878 USACO07JAN] Protecting the Flowers S - 洛谷

【题目描述】

\(n\) 头奶牛跑到 FJ 的花园里去吃花儿了,它们分别在距离牛圈 \(T_i\)(这里指 FJ 到那里需要 \(T_i\) 分钟)处吃花,每分钟会吃掉 \(D_i\) 朵花,FJ 现在要将它们给弄回牛圈,但是他每次只能弄一头回去,来回用时总共为 \(2 \times T_i\) 分钟,在这段时间内,其它的奶牛会继续吃 FJ 的花,速度保持不变,当然正在被赶回牛圈的奶牛不能继续吃了。现在求在最好的方案下奶牛吃掉花的最小朵数。

【输入】

第一行一个正整数 \(n\)

下面 \(n\) 行,每行两个正整数 \(T_i,D_i\)

【输出】

一行一个整数表示答案。

【输入样例】

6
3 1
2 5
2 3
3 2
4 1
1 6

【输出样例】

86

【算法标签】

贪心#

【代码详解】

#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 200005;
int n, sa[N], ans;  // n: 任务数, sa: 后缀和, ans: 答案
struct Node
{
    int t, d;  // t: 完成时间, d: 延迟代价权重
} a[N];

// 比较函数:按t[i]/d[i]从大到小排序
bool cmp(Node x, Node y)
{
    return x.t * y.d > x.d * y.t;  // 等价于x.t/x.d > y.t/y.d,避免浮点数
}
signed main()
{
    cin >> n;  // 输入任务数
    for (int i = 1; i <= n; i++)  // 输入每个任务的时间和延迟权重
    {
        cin >> a[i].t >> a[i].d;
    }
    sort(a + 1, a + n + 1, cmp);  // 按比值排序
    
    // 计算完成时间的后缀和
    for (int i = n; i >= 1; i--)
    {
        sa[i] = sa[i + 1] + a[i].t;
    }
    
    // 计算总延迟代价
    for (int i = 1; i <= n; i++)
    {
        ans += 2 * a[i].d * sa[i + 1];  // 公式:2×d[i]×后面任务的总时间
    }
    cout << ans << endl;  // 输出结果
    return 0;
}

【运行结果】

6
3 1
2 5
2 3
3 2
4 1
1 6
86
posted @ 2026-04-01 16:36  团爸讲算法  阅读(0)  评论(0)    收藏  举报