小Z的AK计划
题目描述
在小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
贪心+优先队列;
1.先把坐标从小到大排序;另外,要AK一个机房,前面的机房时间必须都走过;
2.先把依次路过的机房都去AK,当耗时大于m时,再退掉耗时最大的机房(相当于这个机房不AK,只是路过),直到不大于m;这时可以再往后走,找到最多的AK机房数量;
代码:
#include<bits/stdc++.h>
#define LL long long
#define pa pair<LL,int>
using namespace std;
priority_queue< LL,vector<LL> >qu;
struct Node{
LL x,t;
}an[100100];
bool cmp(Node p,Node q){
return p.x<q.x;
}
int n,ans,mmax;
LL m,sum;
int main(){
scanf("%d%lld",&n,&m);
for(int i=1;i<=n;i++) scanf("%lld%lld",&an[i].x,&an[i].t);
sort(an+1,an+n+1,cmp);
for(int i=1;i<=n;i++){
sum+=an[i].x-an[i-1].x+an[i].t;
qu.push(an[i].t);
ans++;
while(!qu.empty()&&sum>m){
sum-=qu.top();
qu.pop();
ans--;
}
mmax=max(ans,mmax);
if(sum>m) break;//说明这个点已经不能往后走了
}
printf("%d\n",mmax);
return 0;
}