bzoj1071: [SCOI2007]组队

传送门
O(n^3)的应该都会吧(枚举身高最小值,速度最小值和合法人员数量)
正解是O(n^2)乱搞。
先按照A*s+B*h排序,
枚举S最小值,在枚举V的同时维护一个合法人的单调序列,因为这一定是相邻的一串。(我并不晓得为啥,假装他是对的)
好像还是讲不清楚,可以看一下他的

#include<cstring>
#include<cmath>   
#include<cstdio>  
#include<iostream>  
#include<cstdlib>   
#include<algorithm>
#define ll long long
using namespace std;
struct data{ll h,s,sum;}x[5005],y[5005];
ll n,A,B,C,l,r,cnt,ans,mi,ma;
bool cmp1(data a,data b){return a.h<b.h;}
bool cmp2(data a,data b){return a.sum<b.sum;}
bool chk1(int p){return y[p].s>=mi&&y[p].s<=ma;}
bool chk2(int p){return x[p].s>=mi&&x[p].s<=ma;}
int main(){
    scanf("%d%d%d%d",&n,&A,&B,&C);
    for (int i=1;i<=n;i++){
        scanf("%d%d",&x[i].h,&x[i].s);
        x[i].sum=A*x[i].h+B*x[i].s;
        y[i]=x[i];
    }
    sort(x+1,x+n+1,cmp1);
    sort(y+1,y+n+1,cmp2);
    for (int i=1;i<=n;i++){
        l=r=1;
        cnt=0;
        mi=x[i].s;
        ma=mi+C/B;
        for (int j=1;j<=n;j++){
            while (r<=n&&y[r].sum<=A*x[j].h+B*x[i].s+C)
                cnt+=chk1(r++);
            while (l<=n&&x[l].h<x[j].h)
                cnt-=chk2(l++);
            ans=max(ans,cnt);
        }
    }
    printf("%d",ans);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值