Gym 101806T Touch The Sky 思维 优先队列

版权声明:本博客内容基本为原创,如有问题欢迎联系,转载请注明出处 https://blog.csdn.net/qq_41955236/article/details/84502530

题目链接:http://codeforces.com/gym/101806/problem/T

题意:

        你现在在海拔为0的地方,你现在手上有n个气球,每个气球有一个最高可吹海拔L(即如果你当前所在超过了这个高度,你就不能再吹这个气球),和一个吹完之后升高的高度D,每个气球只可被用一次,问你最多可以用几个气球。

做法:

       比赛的时候想到了这个思路,但是没敢深想。。唉。  按照我们上面所讲的,如果我们把一个气球的L和D相加,得到的All会是什么?是我们在吹完这个气球可达到的最高高度,即假设我们使用了这个气球之后,所在的高度只要低于这个All的值,那么这个气球的使用就是合法的。那么我们就可以维护一个气球升高之后的一个最低值。所以当然,我们要先将L+D相加做一次排序,每次加入的时候判断当前高度是否超过了这个气球的合法值,如果超过,那么我们肯定要从我们当前所用的气球里拿出一个升高距离最大的扔掉(因为当到达这个海拔值的时候,如果我们要保证气球不减,只能从当前的气球和已经用掉的气球里做一个取舍,那么很明显,我们就要把升高高度更高的那个扔掉即可)。

       代码量其实很小,唉就是想不到啊。


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=250005;
struct node{
    ll L,D,all;
}e[maxn];
bool cmp(node a,node b){
    return a.all<b.all;
}
int main(){
    int n;
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        scanf("%lld%lld",&e[i].L,&e[i].D);
        e[i].all=e[i].L+e[i].D;
    }
    sort(e+1,e+1+n,cmp);
    ll nowhei=0;
    priority_queue<int> q;
    for(int i=1;i<=n;i++){
        nowhei+=e[i].D;
        q.push(e[i].D);
        if(nowhei>e[i].all){
            int dec=q.top(); q.pop();
            nowhei-=dec;
        }
    }
    printf("%d\n",q.size());
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_41955236/article/details/84502530
sky