bzoj1071: [SCOI2007]组队

来源:互联网 发布:windows消息机制详解 编辑:程序博客网 时间:2024/04/30 19:33

传送门
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 longusing 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);}
0 0
原创粉丝点击