题目描述
问题描述
丑枫接到了一份奇葩的工作:往冰库里搬运冰块.冰库外放着N箱冰块,由于室外温度高,冰块会很快融化,且每箱冰块的融化速度不同.因为每箱冰块的体积,质量不等,把每箱冰块搬运进冰块花费的时间也不同.因此需要合理安排搬运顺序,才能使总的冰块融化量最小.丑枫请你帮忙计算最少的总融化量是多少,以便汇报上司.
输入格式
第一行输入整数N
接下来N行,每行两个整数,分别表示每箱冰块的搬运耗时Ti及融化速度Di.
输出格式
输出最少的总融化量
数据规模和约定
2<=N<=100000,1<=Ti<=4000000,1<=Di<=100
样例输入
6
6 1
4 5
4 3
6 2
8 1
2 6
样例输出
86
(贪心) $O(nlogn)$
思考过程:
使用微扰法,考虑两个冰块的,v1t1+v2(t1+t2)<=v2t2+v1(t1+t2)时融化量最小。
即v2t1<=v1t2即可。估按此排序后计算即可。
C++ 代码
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int N=100010;
struct Ice
{
int a;
long long sum;
}ice[N];
bool cmpsum(Ice q,Ice p)
{
if(q.sum*p.a < p.sum*q.a) return true;
else return false;
}
int main()
{
int n;
cin>>n;
long long m=0;
for(int i=0;i<n;i++)
{
int a,sum;
cin>>a>>sum;
ice[i].a=a;
ice[i].sum=sum;
}
sort(ice,ice+n,cmpsum);
for(int i=0;i<n;i++)
{
m+=ice[i].sum;
ice[i].sum=m;
}
long long res=0;
for(int i=n-1;i>=1;i--)
{
res+=ice[i].a*ice[i-1].sum;
}
cout<<res<<endl;
return 0;
}
