Description
NBA每年都有球员选秀环节。通常用速度和身高两项数据来衡量一个篮球运动员的基本素质。假如一支球队里
速度最慢的球员速度为minV,身高最矮的球员高度为minH,那么这支球队的所有队员都应该满足: A * ( height
– minH ) + B * ( speed – minV ) <= C 其中A和B,C为给定的经验值。这个式子很容易理解,如果一个球队的
球员速度和身高差距太大,会造成配合的不协调。 请问作为球队管理层的你,在N名选秀球员中,最多能有多少名
符合条件的候选球员。
Input
第一行四个数N、A、B、C 下接N行每行两个数描述一个球员的height和speed
Output
最多候选球员数目。
吐槽:
我的方法复杂度为
n2logn
,
n
为
代码:
#include<cstdio>
#include<cstring>
#include<queue>
#include<iostream>
#include<algorithm>
using namespace std;
#define LL long long
LL A,B,C;
int N;
struct player
{
LL height,speed,val;
bool operator <(const player a) const
{return val<a.val;}
}a[5010];
bool cmp(player x,player y){return x.speed>y.speed;}
priority_queue<LL>q;
LL ans=1LL;
int main()
{
scanf("%d%lld%lld%lld",&N,&A,&B,&C);
for(int i=1;i<=N;i++)
{
scanf("%lld%lld",&a[i].height,&a[i].speed);
a[i].height*=A;a[i].speed*=B;a[i].val=a[i].height+a[i].speed;
}
sort(a+1,a+1+N,cmp);
for(int i=1;i<=N;i++)//枚举当前height的最小值
{
LL minh=a[i].height,mins=a[i].speed;
while(!q.empty())q.pop();
q.push(a[i].val);
for(int j=1;j<=N;j++)//枚举j
if(j!=i&&a[j].height>=a[i].height)
{
mins=min(mins,a[j].speed);
if(a[i].val>C+mins+minh)break;//因为minh+C不会变,而mins单调递减,所以可以break
while(!q.empty()&&q.top()>C+mins+minh)q.pop();//踢人
if(a[j].val<=C+mins+minh)//判断j是否可以加入,可以则更新答案
{
q.push(a[j].val);
ans=max(ans,(LL)(q.size()));
}
}
}
printf("%lld",ans);
}