zoukankan      html  css  js  c++  java
  • 【GOJ 3038】逛餐馆

    传送门

    解析

    显然我们只会往一个方向走,不会回头(回头一定浪费时间)。那我们将所有餐馆序。

    那我们不妨枚举我们能走到最远的餐馆,假设我们枚举我们走到第 (i)个餐馆(排完序之后)。
    那么我们就是在 (1) ~ (i) 餐馆中寻若干个餐馆,使他们和不超过 (m-x_i),然后求最多的个数即可。那显然就是在 (1) ~ (i) 餐馆中按照 (t_i) 从小到大排序,然后不断累加直至超过 (m-x_i) 的餐馆个数。

    这个经典題目用优先队列来维护即可。

    我们维护一个大根堆,这个堆里面维护 (1) ~ (i) 所有餐馆中,最小的若干个餐馆,并且他们和 (le m-x_i)

    那我们从 (1)(n) 枚举 (i) ,每次执行三个操作:

    1. (t_i) 加进堆里面。
    2. 若堆中元素之和大于 (m-x_i),则不断弹出堆顶元素直到总和小于等于 (m-x_i)
    3. 堆的大小就是我们能吃的餐馆的个数,用这个更新答案。

    时间复杂度为 (O(n log_2n))

    代码

    #include<bits/stdc++.h>
    using namespace std;
    using LL=long long;
    const LL N=1e5+5;
    struct jvav {
    	LL x,t;
    	void read() {
    		scanf("%lld %lld",&x,&t);
    	}
    	bool operator<(const jvav &bee) const {
    		return x<bee.x;
    	}
    } a[N];
    priority_queue<LL> q;
    int main() {
    	LL n,m;
    	scanf("%lld %lld",&n,&m);
    	for(LL i=1; i<=n; i++) {
    		a[i].read();
    	}
    	sort(a+1,a+n+1);
    	LL sum=0,ans=0;
    	for(LL i=1; i<=n; i++) {
    		q.push(a[i].t),sum+=a[i].t;
    		while(q.size()&&sum>m-a[i].x) {
    			sum-=q.top(),q.pop();
    		}
    		if(ans<q.size()) {
    			ans=q.size();
    		}
    	}
    	printf("%lld",ans);
    	return 0;
    }
    
  • 相关阅读:
    一个编程的代码网址
    FireFox竟然成功抢注ie7.com域名
    呀!天空软件真的被百度收购了
    呀!天空软件真的被百度收购了
    一个编程的代码网址
    不只MSN会被监听,QQ也一样的
    FireFox竟然成功抢注ie7.com域名
    MS06014网马的一种变形方法
    小马ASP
    Etoile-又一个桌面气象
  • 原文地址:https://www.cnblogs.com/Sam2007/p/13673202.html
Copyright © 2011-2022 走看看