您的位置:首页 > 其它

bzoj1071: [SCOI2007]组队

2017-03-17 21:13 351 查看
传送门

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 chk
4000
1(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);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: