题目描述
在小Z的家乡,有机房一条街,街上有很多机房。每个机房里都有一万个人在切题。小Z刚刷完CodeChef,准备出来逛逛。
机房一条街有 n 个机房,第 i 个机房的坐标为 xi ,小Z的家坐标为 0。小Z在街上移动的速度为1,即从 x1 到 x2 所耗费的时间为 |x1 − x2|。 每个机房的学生数量不同,ACM 题目水平也良莠不齐。小Z到达第 i 个机房后,可以花 ti 的时间想题,然后瞬间 AK;当然,也可以过机房而不入。
小Z现在只有 m 个单位时间,之后他就该赶着去打 Codeforces 了。现在他想知道自己最多能在多少个机房 AK,希望你帮帮他。
输入格式
第一行包含两个整数 n,m。
接下来 n 行,每行包含两个整数 xi,ti 。
输出格式
第一行包含一个整数,表示小Z最多能 AK 的机房数量。
输入输出样例
输入 #1 复制
2 10
1 100
5 5
输出 #1 复制
1
说明/提示
【数据规模】
对于 30% 的数据,n ≤ 20。
对于 60% 的数据,n ≤ 1000。
对于 100% 的数据,1 ≤ n ≤ 10^5,0 ≤ m,xi ≤ 10^18,0 ≤ ti ≤ 10^9。
这道题我们可以这样想:假设我们从起点开始走,能进去ak就进去ak,如果当时的时间已经超过了m,那我们就会选择前面的不ak,或者现在这个不ak(因为x走路是必须要花费的,所以不能考虑从走路节约时间),那么我们会选择哪个不ak呢?肯定是时间大的呀,所以我们用一个堆维护前面ak所需时间。每次更新答案即可。
AC代码:
#pragma GCC optimize(2)
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e5+10;
int n,m,res,cnt,tim,s;
struct node{
int x,t;
}a[N];
priority_queue<int> pq;
int cmp(node s1,node s2){
return s1.x<s2.x;
}
signed main(){
cin>>n>>m;
for(int i=1;i<=n;i++) cin>>a[i].x>>a[i].t;
sort(a+1,a+1+n,cmp);
for(int i=1;i<=n;i++){
int tim=m-a[i].x; if(tim<0) break;
s+=a[i].t; pq.push(a[i].t); cnt++;
if(tim>=s) res=max(res,cnt);
else{
while(tim<s){
s-=pq.top(); pq.pop(); cnt--;
}
res=max(res,cnt);
}
}
cout<<res<<endl;
return 0;
}