問題
所与のA、B、C、及びnタプル(x、y)とします。( - MINY Y)\ルC $ Qは、$ A \回(X-ミンクス)+ B \回タプル選択満たすタプルの最大数から選択されます。前記$ミンクス、MINY $それぞれ選択されたビンおよび最小のX、Y。
溶液
タイトルは式を開始しました。
\(アックス - Aminx +別 - Bminy \ルC \)
\(アックス+することで\ルC + Aminx + Bminy \)
$によって$ S =アックス+提供。列挙ミンクスを考えてみましょう。そして、小さなから大規模までMINYを列挙します。
タプルは、ソートsおよびyは。ポインタ・アレイを移動させるためのLはBminy $の$アックス+により\ルC + Aminx +数を満たす数を表し、Sでソート。ポインタ・アレイを移動させるためのRは、$ Y \ GE MINY $位置を満たす数を表し、Yでソート。
MINY列挙小さいが大きいために、lが、右に移動し続けるようとき一段右、Y> Y Rの位置を横切る位置は、意志ANS ++と呼ぶ場合。現在の場所は$ yの\ GE MINY $を満たしていない場合でもので、我々はそれを削除することができたときに彼の後ろに移動rを。場所は答えの統計渡って発見された場合は、当然にも、R、右に移動するプロセスを移動していきます、それはans--ます。その後、充電が統計的な答えを漏洩しないことはできません。
コード
/*
* @Author: wxyww
* @Date: 2019-12-14 08:43:08
* @Last Modified time: 2019-12-14 10:21:15
*/
#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<queue>
#include<vector>
#include<ctime>
using namespace std;
typedef long long ll;
const int N = 5010;
ll read() {
ll x = 0,f = 1;char c = getchar();
while(c < '0' || c > '9') {
if(c == '-') f = -1; c = getchar();
}
while(c >= '0' && c <= '9') {
x = x * 10 + c - '0'; c = getchar();
}
return x * f;
}
struct node {
int h,v; ll w;
}a[N],b[N];
bool cmp1(const node &A,const node &B) {
return A.w < B.w;
}
bool cmp2(const node &A,const node &B) {
return A.h < B.h;
}
int main() {
int n = read();ll A = read(),B = read(),C = read();
for(int i = 1;i <= n;++i) {
a[i].h = read(),a[i].v = read();
a[i].w = a[i].h * A + a[i].v * B;
b[i] = a[i];
}
sort(b + 1,b + n + 1,cmp1);
sort(a + 1,a + n + 1,cmp2);
int ans = 0;
for(int i = 1;i <= n;++i) {
int minV = a[i].v;int l = 0,r = 0,now = 0;
for(int j = 1;j <= n;++j) {
int minH = a[j].h;
while(b[l + 1].w <= C + A * minH + B * minV && l < n) {
++l;
if(b[l].v < minV) continue;
if(b[l].h > a[r].h) ++now;
}
while(a[r + 1].h < minH && r < n) {
++r;
if(a[r].v < minV) continue;
if(a[r].w <= C + A * minH + B * minV) --now;
}
ans = max(ans,now);
}
}
cout<<ans<<endl;
return 0;
}