题目大意:
给你n个瓶饮料,每个饮料有一个值,喝下去生命值会增加该值,让你从左到右依次,对待每个饮料有两种选择,喝or不喝,与此同时,要保证生命值在是、任何时期为非负数。
刚开始觉得这道题要用dp,(奈何本菜鸡不会dp),又看到了其他大佬优先队列的思路,然后自己写了一下,A了。
这里补充一下优先队列的知识:
大佬的csdn
和队列基本操作相同:
top 访问队头元素
empty 队列是否为空
size 返回队列内元素个数
push 插入元素到队尾 (并排序)
emplace 原地构造一个元素并插入队列
pop 弹出队头元素
swap 交换内容
升序和降序队列:
//升序队列
priority_queue <int,vector,greater > q;
//降序队列
priority_queue <int,vector,less >q;
//greater和less是std实现的两个仿函数(就是使一个类的使用看上去像一个函数。其实现就是类中实现一个operator(),这个类就有了类似函数的行为,就是一个仿函数类了)
AC代码:
#include<iostream>
#include<string.h>
#include<algorithm>
#include<stdio.h>
#include<queue>
typedef long long ll;
using namespace std;
int main()
{
priority_queue <ll,vector<ll>,greater<ll> > q; //升序排列
int n;
scanf("%d",&n);
long long ans=0;
int sum=0; //记录喝饮料的数量
for(int i=0;i<n;i++){
long long x;
scanf("%lld",&x);
if(x>=0){ //若大于0则,一定喝
ans+=x;
sum++;
}
else{
if(ans+x>=0){
ans+=x;
sum++;
q.push(x);
}
else{
if(!q.empty()&&x>q.top()){ //如果该饮料大于之前喝的某种饮料,则把该饮料换成之前喝的那种饮料
ans=ans-q.top();
q.pop();
q.push(x);
ans+=x;
}
}
}
} printf("%d",sum);
}