指针胡乱跳
利用单调性降次
/************************************************************** Problem: 1071 User: lxy8584099 Language: C++ Result: Accepted Time:2744 ms Memory:1064 kb ****************************************************************/ /* 将式子拆开就是 C + A*minH + B*minV >= A*h + B*v 结构体 一个a按 h排序 b一个按 A*h+B*v排序 外层随便顺序枚举minV 内层增序枚举 minH 指针p1从1开始 在b数组里面判断 A*h + B*v <= C + A*minH + B*minV 其中有满足 v >= minV && 此 v 不会让h做负的贡献值(意思是v不会太大 ans++; 这里是算出所有 符合minV 和 C + A*minH + B*minV条件的 没有符合 minH 指针p2从1开始 在a数组里面判断 h< minH 其中有满足 v >= minV && 此 v 不会让h做负的贡献值(意思是v不会太大 ans--; 在这里 h是小于 minH 但又符合minV 和 C + A*minH + B*minV条件的 所以ans要减去这部分算进去了的 但又不符合条件的 */ #include<cstdio> #include<algorithm> #define ll long long using namespace std; const int N=5050; struct pp {ll h,v,s;} a[N],b[N]; inline bool cmp1(pp a,pp b) {return a.h<b.h;} inline bool cmp2(pp a,pp b) {return a.s<b.s;} inline int max(int a,int b) {return a>b?a:b;} ll A,B,C; int ans,n; int main() { scanf("%d%lld%lld%lld",&n,&A,&B,&C); for(int i=1;i<=n;i++) { scanf("%lld%lld",&a[i].h,&a[i].v); a[i].s=A*a[i].h+B*a[i].v; b[i]=a[i]; } sort(a+1,a+n+1,cmp1); sort(b+1,b+n+1,cmp2); for(int minv=1;minv<=n;minv++) // 随便枚举minv 不放就按a顺序的来 { int p1=0,p2=0,res=0;ll ed=C/B+a[minv].v; for(int minh=1;minh<=n;minh++) // 从小到大枚举 minh { // ed就是v==minv==0的时候 满足原式子 B除过去就成 while(p1<n&&b[p1+1].s<=C+A*a[minh].h+B*a[minv].v) // bs单增 if(b[++p1].v>=a[minv].v&&b[p1].v<=ed) res++; while(p2<n&&a[p2+1].h<a[minh].h) // ah单增 if(a[++p2].v>=a[minv].v&&a[p2].v<=ed) res--; ans=max(ans,res); } } printf("%d\n",ans); return 0; }