接水问题Ⅱ
题目
n个人一起排队接水,第i个人的重要性是ai,需要bi的时间来接水。
1 <= n <= 100000
0 <= bi <= 1000
0 <= ai <= 1000
同时只能有一个人接水,正在接水的人和没有接水的人都需要等待。
完成接水的人会立刻消失,不会继续等待。
你可以决定所有人接水的顺序,并希望最小化所有人等待时间乘以自己的重要性ai的总和。
input
第一行一个整数n。 以下n行,每行两个整数ai和bi。
样例
input
4
1 4
2 3
3 2
4 1
output
35
思路
重要性和等待时间是一个人的属性,想到用结构体
总和:
situation 1: sum=a[i].aia[i].bi+b[i].ai(b[i].bi+a[i].bi);
situation 2: sum=b[i].aib[i].bi+a[i].ai(a[i].bi+b[i].bi);
二者差别为a[i].bib[i].ai和b[i].aia[i].bi的大小差别,按增序排列,即可得出答案
本题注意
0 <= bi <= 1000
0 <= ai <= 1000
这种情况下,bi和ai为0时,会干扰排序
例如ai=0,bi!=0时,二者相乘为0,但time!=0,使sum出错!!!
代码
#include<bits/stdc++.h>
using namespace std;
#define N 100002
struct person
{
int ai;
int bi;
};
bool cmp(person m1,person m2)
{
return m1.ai*m2.bi>m2.ai*m1.bi;
}
int main()
{
int n;
long long sum=0,time=0;
cin>>n;
person p[N];
for(int i=0;i<n;i++)
{
cin>>p[i].ai
>>p[i].bi;
//题目范围0<=bi<=1000,当bi或ai为0时,无意义,还会干扰排序,删除掉
if(p[i].ai==0||p[i].bi==0)
{
i--;
n--;
}
}
sort(p,p+n,cmp);
for(int i=0;i<n;i++)
{
time+=p[i].bi;
sum+=p[i].ai*time;
}
cout<<sum<<endl;
return 0;
}