题目描述
约翰留下他的N(N<=100000)只奶牛上山采木.他离开的时候,她们像往常一样悠闲地在草场里吃草.可是,当他回来的时候,他看到了一幕惨剧:牛们正躲在他的花园里,啃食着他心爱的美丽花朵!为了使接下来花朵的损失最小,约翰赶紧采取行动,把牛们送回牛棚. 牛们从1到N编号.第i只牛所在的位置距离牛棚Ti(1≤Ti≤2000000)分钟的路程,而在约翰开始送她回牛棚之前,她每分钟会啃食Di(1≤Di≤100)朵鲜花.无论多么努力,约翰一次只能送一只牛回棚.而运送第第i只牛事实上需要2Ti分钟,因为来回都需要时间. 写一个程序来决定约翰运送奶牛的顺序,使最终被吞食的花朵数量最小.
输入输出格式
输入格式:
第1行输入N,之后N行每行输入两个整数Ti和Di
输出格式:
一个整数,表示最小数量的花朵被吞食
输入输出样例
输入样例#1:
6 3 1 2 5 2 3 3 2 4 1 1 6
输出样例#1:
86 【样例解释】 约翰用6,2,3,4,1,5的顺序来运送他的奶牛
分析:要安排顺序,很显然是一道贪心题,那么要怎么安排顺序呢?
还是依靠贪心的一般套路,选2头牛a,b,假设(a,b)是最佳的顺序,如果交换a,b,那么答案一定会比不交换差,也就是说要ta*db*2 < tb*da*2,推广到一般情况也是一样的,依照这个排序然后模拟一下就好了。
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #include <cmath> using namespace std; const int maxn = 100010; int n,sum; long long ans; struct node { int t, d; }e[maxn]; bool cmp(node a, node b) { return a.t * b.d < a.d * b.t; } int main() { scanf("%d", &n); for (int i = 1; i <= n; i++) { scanf("%d%d", &e[i].t, &e[i].d); sum += e[i].d; } sort(e + 1, e + 1 + n, cmp); for (int i = 1; i <= n; i++) { sum -= e[i].d; ans += sum * e[i].t * 2; } printf("%lld ", ans); return 0; }