[BZOJ]1071: [SCOI2007]组队 STL优先队列

5 篇文章 0 订阅

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 2000,竟然可以过……

代码:

#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);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值