题解:洛谷 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
浙公网安备 33010602011771号