[bzoj1071] [SCOI2007]组队

Description

  NBA每年都有球员选秀环节。通常用速度和身高两项数据来衡量一个篮球运动员的基本素质。假如一支球队里速度最慢的球员速度为minV,身高最矮的球员高度为minH,那么这支球队的所有队员都应该满足: A * ( height – minH ) + B * ( speed – minV ) <= C 其中A和B,C为给定的经验值。这个式子很容易理解,如果一个球队的球员速度和身高差距太大,会造成配合的不协调。 请问作为球队管理层的你,在N名选秀球员中,最多能有多少名符合条件的候选球员。

Input

  第一行四个数N、A、B、C 下接N行每行两个数描述一个球员的height和speed

Output

  最多候选球员数目。

Sample Input

4 1 2 10
5 1
3 2
2 3
2 1

Sample Output

4

Solution

把式子化开,可以得到:

\[A\cdot h+B\cdot s\leqslant A\cdot mnh+B\cdot mns+C \]

然后我们就得到了一个\(O(n^3)\)的做法:枚举\(mnh,mns\),然后枚举每一个合不合法。

考虑这个怎么优化,首先枚举最小值的时候从小到大枚举,那么枚举\(mns\)的时候不等式的右边就会单调递增,那么我们可以按照左边排序,然后从小到大加。

注意到这里还要两个限制:\(h\geqslant mnh,s\geqslant mns\),然后就有一个很神奇的做法:

先不考虑\(s\)带来的影响,那么对于\(h\),显然要满足\(mnh\leqslant h \leqslant mnh+C/A\),然后把满足这些条件的加进去,

对于\(s\),如果满足以上条件,但是\(s<mns\),那么就把这个删掉。

然后合法的一定是连续一段,所以上面的做法是对的。

可以发现以上都是单调的,所以总复杂度\(O(n^2)\)

#include<bits/stdc++.h>
using namespace std;
 
#define int long long 
 
void read(int &x) {
    x=0;int f=1;char ch=getchar();
    for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-f;
    for(;isdigit(ch);ch=getchar()) x=x*10+ch-'0';x*=f;
}
 
void print(int x) {
    if(x<0) putchar('-'),x=-x;
    if(!x) return ;print(x/10),putchar(x%10+48);
}
void write(int x) {if(!x) putchar('0');else print(x);putchar('\n');}

const int maxn = 2e5+10;

int n,A,B,C,tx[maxn],ans,q[maxn];
struct data {int x,y,sum;}a[maxn],b[maxn],c[maxn];

int cmpx(data x,data y) {return x.x<y.x;}
int cmpy(data x,data y) {return x.y<y.y;}
int cmpsum(data x,data y) {return x.sum<y.sum;}

signed main() {
	read(n),read(A),read(B),read(C);
	for(int i=1;i<=n;i++) read(a[i].x),read(a[i].y),b[i].x=c[i].x=a[i].x,b[i].y=c[i].y=a[i].y;
	for(int i=1;i<=n;i++) c[i].sum=c[i].x*A+c[i].y*B;
	sort(a+1,a+n+1,cmpx);
	sort(b+1,b+n+1,cmpy);
	sort(c+1,c+n+1,cmpsum);
	for(int i=1;i<=n;i++) {
		int mn=a[i].x,mx=a[i].x+C/A,p1=0,p2=0,cnt=0;
		for(int j=1;j<=n;j++) {
			int lim=C+a[i].x*A+b[j].y*B;
			while(p1<n&&c[p1+1].sum<=lim)
				p1++,cnt+=(c[p1].x>=mn&&c[p1].x<=mx);
			while(p2<n&&b[p2+1].y<b[j].y)
				p2++,cnt-=(b[p2].x>=mn&&b[p2].x<=mx);
			ans=max(ans,cnt);
		}
	}write(ans);
	return 0;
}
posted @ 2019-02-22 14:47  Hyscere  阅读(105)  评论(0编辑  收藏  举报