Description
NBA每年都有球員選秀環節。通常用速度和身高兩項數據來衡量一個籃球運動員的基本素質。假如一支球隊裏速度最慢的球員速度爲minV,身高最矮的球員高度爲minH,那麼這支球隊的所有隊員都應該滿足: A * ( height – minH ) + B * ( speed – minV ) <= C 其中A和B,C爲給定的經驗值。這個式子很容易理解,如果一個球隊的球員速度和身高差距太大,會造成配7合的不協調。 請問作爲球隊管理層的你,在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
HINT
1 <= N <= 5000,0<= height,speed <= 10000,A、B、C在長整型以內且爲正數。
Solution
- 可以想到n^3的暴力枚舉方法
- 但是時間會爆,想想優化
- 天外飛來兩個推導式:hi <= C/A + H && Ahi + Bvi <= AH+B*V+C
- 枚舉H用這兩個式子判斷vi的合法性
#include <bits/stdc++.h>
#define il inline
#define re register
using namespace std;
typedef long long ll;
const int maxn = 5010;
int n, a, b, c;
int ans;
struct node{
int h, v;
int w;
}eh[maxn], ew[maxn];
il bool cmph(node x, node y) {
return x.h < y.h;
}
il bool cmpw(node x, node y) {
return x.w < y.w;
}
int main() {
ans = 0;
scanf("%d%d%d%d", &n, &a, &b, &c);
for(re int i = 1; i <= n; ++i) {
scanf("%d%d", &eh[i].h, &eh[i].v);
eh[i].w = a*eh[i].h + b*eh[i].v;
ew[i] = eh[i];
}
sort(eh+1, eh+n+1, cmph);
sort(ew+1, ew+n+1, cmpw);
for(re int i = 1; i <= n; ++i) {
//枚舉v
int minv = eh[i].v;
int l = 1, r = 1, cnt = 0;
for(re int j = 1; j <= n; ++j) {
//因爲h有序,所以從左到右移就行
int minh = eh[j].h;
while(r <= n && ew[r].w <= a*minh + b*minv + c) {
if(ew[r].v >= minv && ew[r].v <= c/b + minv)//合法(要加)
cnt++;
r++;
}
while(l <= n && eh[l].h < minh) {//不合法
if(eh[l].v >= minv && eh[l].v <= c/b + minv)//合法(已加)
cnt--;
l++;
}
ans = max(ans, cnt);
}
}
printf("%d\n", ans);
return 0;
}