[SCOI2007]组队
题面
题解
题意要求求出当以一个H和一个V为最小值的时候,满足A*(H-minH)+B *(V-minV)<=C的个数
显然最简单的做法是枚举出minH和minV的值,在循环一遍找那些符合,然而这种做法并不适用于5000的数据
考虑讲时间复杂度优化到O(N2)
注意到当MinH一定时,此时任意一个H>minH ,有V<=C/B + minV
代码
#include<bits/stdc++.h> using namespace std; inline int read() { int f=1,x=0; char ch; do { ch=getchar(); if(ch=='-') f=-1; }while(ch<'0'||ch>'9'); do { x=(x<<3)+(x<<1)+ch-'0'; ch=getchar(); }while(ch>='0'&&ch<='9'); return f*x; } struct Player { long long v; long long h; long long s; }; long long n,a,b,c; Player p[5000 + 10],p2[5000 + 10]; long long ans; inline bool cmp1(Player a,Player b) { return a.h<b.h; } inline bool cmp2(Player a,Player b) { return a.s<b.s; } int main() { n=read();a=read();b=read();c=read(); for(int i=1;i<=n;i++) { p[i].h=read(); p[i].v=read(); p[i].s=p[i].h*a+p[i].v*b; p2[i]=p[i]; } sort(p+1,p+n+1,cmp1); sort(p2+1,p2+n+1,cmp2); for(int i=1;i<=n;i++) { long long l=0,r=0;long long cnt=0; long long MAXI = c/b+p[i].v; for(int j=1;j<=n;j++) { while(r<n&&p2[r+1].s<=c+a*p[j].h+b*p[i].v) { if(p[i].v<=p2[++r].v&&p2[r].v<=MAXI) { cnt++; } } while(l<n&&p[l+1].h<p[j].h) { if(p[i].v<=p[++l].v&&p[l].v<=MAXI) { cnt--; } } ans=max(ans,cnt); } } cout<<ans<<endl; }