NBA每一年都有球員選秀環節。一般用速度和身高兩項數據來衡量一個籃球運動員的基本素質。假如一支球隊裏速度最慢的球員速度爲minV,身高最矮的球員高度爲minH,那麼這支球隊的全部隊員都應該知足: A * ( height
– minH ) + B * ( speed – minV ) <= C 其中A和B,C爲給定的經驗值。這個式子很容易理解,若是一個球隊的球員速度和身高差距太大,會形成配合的不協調。 請問做爲球隊管理層的你,在N名選秀球員中,最多能有多少名符合條件的候選球員。c++
第一行四個數N、A、B、C 下接N行每行兩個數描述一個球員的height和speed數組
最多候選球員數目。spa
4 1 2 10
5 1
3 2
2 3
2 1指針
4code
數據範圍: N <= 5000 ,height和speed不大於10000。A、B、C在長整型之內。排序
這題也真是夠神仙的隊列
首先把式子變成這樣ip
$Ax+By-C\le Aminx + Bminy $input
而後就從新取一個權值叫作\(val=Ax+By-C\)it
把原數組複製兩遍,一個按照x排序,一個按照val排序
而後咱們先枚舉miny,而後在內層枚舉minx,可是同時怎麼維護答案?
咱們用一個指針掃val加入答案,並用一個指針掃x刪除答案
我第一次看到的時候心情就是wtf?
確實很神奇
如今咱們考慮加入答案的限制,首先y確定是要大於等於miny的,可是y應該有一個上界,否則\(y-miny\)太大致使在知足\(val\le Aminx+Bminy\)的條件下\(x< minx\)
既然不能讓x超界,也就是要知足\(minx\le x\),那麼就必定有
\(By\le Bminy + C\)
也就是說\(miny\le y\le miny + \frac{C}{B}\)
這樣就能夠同時掃按照x排序的隊列來把x不知足的都刪掉了(由於y對於全局的限制都是相等的)
???
好像推不過來吧,不過沒事,在這道題裏面是對的
如今來考慮另外一個事情:會不會有沒有統計貢獻的被刪除貢獻?
不可能的
被刪除貢獻的時候須要知足\(x<minx\)和\(min\le y\le miny+\frac{C}{B}\)
顯然是知足\(Ax+By\le Aminx+Bminy+C\)的
那不就必定會在上面統計貢獻嗎?
因此就成立了。。。而後其實你也能夠根據剛剛這個式子把\(By\le Bminy + C\)理解爲讓刪除不重不漏的條件
#include<bits/stdc++.h> using namespace std; const int N = 5010; int n, A, B, C; int ans; struct Point { int x, y, val; Point() {} Point(int x, int y, int val): x(x), y(y), val(val) {} } p[N], q[N]; bool cmp1(const Point a, const Point b) { return a.x < b.x; } bool cmp2(const Point a, const Point b) { return a.val < b.val; } int main() { scanf("%d %d %d %d", &n, &A, &B, &C); for (int i = 1; i <= n; i++) { int x, y; scanf("%d %d", &x, &y); p[i] = q[i] = Point(x, y, A * x + B * y - C); } sort(p + 1, p + n + 1, cmp1); sort(q + 1, q + n + 1, cmp2); for (int i = 1; i <= n; i++) { int tp = 0, tq = 0, cur = 0; int dn = p[i].y, up = C / B + p[i].y; for (int j = 1; j <= n; j++) { int limit = A * p[j].x + B * p[i].y; while (tp < n && p[tp + 1].x < p[j].x) { ++tp; cur -= dn <= p[tp].y && p[tp].y <= up; } while (tq < n && q[tq + 1].val <= limit) { ++tq; cur += dn <= q[tq].y && q[tq].y <= up; } ans = max(ans, cur); } } printf("%d", ans); return 0; }