题目描述
情人节又到了,又到了一年一度发红包的时间。经大家研究决定,今年让奎奎自愿发红包。
俱乐部有n个人(0<n<100000),每个人都有一个单身值v[i]与亲密度t[i](0≤v[i]≤10000,0≤t[i]≤10000),单身值越大的人,在情人节的时候就越羡慕奎奎,奎奎就需要给他更大的红包来安慰他。 由于一个寒假没有见到奎奎,领红包的时候大家都想跟奎奎py,花费时间t[i],先py后给红包噢。
大家都厌倦了等待,如果一个人等了时间t,那么奎奎发给他的红包大小就是v[i]·t。
但是奎奎还要和女朋友去快乐,想要花最少的钱来满足大家。
请你帮他计算最少需要发多少钱的红包。
输入
第一行一个整数n。接下来n行,每行两个数v[i]和t[i]。
输出
一个整数表示答案。
样例输入 Copy
4 1 4 2 3 3 2 4 1
样例输出 Copy
35
题目分析:签到题贪心。。请教的ybl大佬,我真的太弱了
每个人都有两个属性 v[ i ] 和 t[ i ],考虑前后两个人,x 和 y 的相对位置:
- 如果 x 在前 y 在后:v[ x ] * t[ x ] + v[ y ] * ( t[ x ] + t[ y ] ) = v[ x ] * t[ x ] + v[ y ] * t[ x ] + v[ y ] * t[ y ]
- 如果 y 在前 x 在后:v[ y ] * t[ y ] + v[ x ] * ( t[ x ] + t[ y ] ) = v[ y ] * t[ y ] + v[ x ] * t[ x ] + v[ x ] * t[ y ]
也就是说,当 v[ x ] * t[ x ] + v[ y ] * t[ x ] + v[ y ] * t[ y ] < v[ y ] * t[ y ] + v[ x ] * t[ x ] + v[ x ] * t[ y ] 时,x 在前
可能这样看着还是有点乱,约分一下: v[ y ] * t[ x ] < v[ x ] * t[ y ] 时,x 在前
然后排序一下就好了
代码:
#include<iostream>
#include<cstdio>
#include<string>
#include<ctime>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<stack>
#include<climits>
#include<queue>
#include<map>
#include<set>
#include<sstream>
using namespace std;
typedef long long LL;
typedef unsigned long long ull;
const int inf=0x3f3f3f3f;
const int N=1e5+100;
struct Node
{
int v,t;
void input()
{
scanf("%d%d",&v,&t);
}
bool operator<(const Node& a)const
{
return a.v*t<a.t*v;
}
}a[N];
int main()
{
#ifndef ONLINE_JUDGE
// freopen("input.txt","r",stdin);
// freopen("output.txt","w",stdout);
#endif
// ios::sync_with_stdio(false);
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++)
a[i].input();
sort(a+1,a+1+n);
LL ans=0,time=0;
for(int i=1;i<=n;i++)
{
time+=a[i].t;
ans+=time*a[i].v;
}
printf("%lld\n",ans);
return 0;
}