题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1634
题意:
约翰留下他的N只奶牛上山采木。可是,当他回来的时候,他看到了一幕惨剧:牛们正躲在他的花园里,啃食着他心爱的美丽花朵!
为了使接下来花朵的损失最小,约翰赶紧采取行动,把牛们送回牛棚。
第i只牛所在的位置距离牛棚t[i](1 <= t[i] <= 2000000)分钟的路程,而在约翰开始送她回牛棚之前,她每分钟会啃食e[i](1 <= e[i] <= 100)朵鲜花。
无论多么努力,约翰一次只能送一只牛回棚。而运送第第i只牛事实上需要2Ti分钟,因为来回都需要时间。
写一个程序来决定约翰运送奶牛的顺序,使最终被吞食的花朵数量最小。
题解:
贪心。
对于顺序相邻的两只牛a和b,交换a和b的顺序,对于a和b之外的牛是没有影响的。
将其他的牛看作一只牛c。
当a排在b之前时,答案为:
ans1 = t[a]*(e[b]+e[c]) + t[b]*e[c]
当b排在a之前时,答案为:
ans2 = t[b]*(e[a]+e[c]) + t[a]*e[c]
假设a排在b前面的时候答案更优,则有:
ans1 < ans2
即:t[a]*(e[b]+e[c]) + t[b]*e[c] < t[b]*(e[a]+e[c]) + t[a]*e[c]
整理得:t[a]*e[b] < t[b]*e[a]
所以按照t[a]*e[b] < t[b]*e[a]排序就好了。
AC Code:
// before: t[a]*(e[b]+e[c]) + t[b]*e[c]
// after: t[b]*(e[a]+e[c]) + t[a]*e[c]
// if a is better:
// t[a]*(e[b]+e[c]) + t[b]*e[c] < t[b]*(e[a]+e[c]) + t[a]*e[c]
// t[a]*e[b] + t[a]*e[c] + t[b]*e[c] < t[b]*e[a] + t[b]*e[c] + t[a]*e[c]
// t[a]*e[b] < t[b]*e[a]
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
#define MAX_N 100005 using namespace std; struct Cow
{
int eat;
int tim;
Cow(int _eat,int _tim)
{
eat=_eat;
tim=_tim;
}
Cow(){}
friend bool operator < (const Cow &a,const Cow &b)
{
return a.tim*b.eat<b.tim*a.eat;
}
}; int n;
long long ans=;
Cow cow[MAX_N]; void read()
{
cin>>n;
for(int i=;i<n;i++)
{
cin>>cow[i].tim>>cow[i].eat;
cow[i].tim<<=;
}
} void solve()
{
sort(cow,cow+n);
int tot=;
for(int i=;i<n;i++)
{
tot+=cow[i].eat;
}
for(int i=;i<n;i++)
{
tot-=cow[i].eat;
ans+=cow[i].tim*tot;
}
} void print()
{
cout<<ans<<endl;
} int main()
{
read();
solve();
print();
}