【题目描述】:
你在一场激烈的战斗之后体力已经消耗一空,好在你来到了补给点。
补给点有一排 N 瓶药剂,药剂编号 1∼N( N≤200,000),喝下第 i 瓶药剂会补充你的体力 ai,ai 可能为负数,这意味着该药剂会消耗你的体力 ai。
起初你的体力为 00,你从 11 号药剂开始直到 N 号药剂,在每一瓶药剂前,你可以选择喝下或忽略药剂(由于药剂口感很好,你希望喝的越多越好)。
注意:在任何时刻,你必须保证自己的体力不能为负。
你能喝的药剂最多是多少瓶?
【输入描述】:
第一行一个正整数 N(1≤n≤200,000);
第二行 N 个整数,表示 a1∼aN(−109≤ai≤109);
【输出描述】:
一行一个非负整数,表示你能喝的最多药剂数。
【样例输入】:
6
4 -4 1 -3 1 -3
【样例输出】:
5
【样例说明】:
选择第 1、3、4、5、61、3、4、5、6 瓶药剂,分别是:4、1、−3、1、−3体力任何时刻不会为负。
分析与解:
用一个优先队列存储走过能量为负的试剂,当体力为负数的时候,就将负能量最大的试剂弹出,最后剩下的加上正能量的试剂数即答案。
贴上代码:
#include <bits/stdc++.h>
#define ll long long
using namespace std;
template <typename T>
void in(T &x) {
char c = getchar();
int f = 1;
while ((c > '9' || c < '0') && c != '-') {
c = getchar();
}
if (c == '-') {
f = -1;
c = getchar();
}
for (x = 0; c >= '0' && c <= '9'; c = getchar()) {
x = x * 10 + c - '0';
}
x *= f;
}
ll n;
ll ans;
ll sum;
ll a[200005];
priority_queue<ll, vector<ll>, less<ll> > q;
int main() {
freopen("potions.in", "r", stdin);
freopen("potions.out", "w", stdout);
in(n);
for (ll i = 1; i <= n; i++) {
in(a[i]);
}
for (ll i = 1; i <= n; i++) {
if (a[i] < 0) {
q.push(abs(a[i]));
}
sum += a[i];
ans++;
if (sum < 0) {
ll k = q.top();
sum += k;
ans--;
q.pop();
}
}
printf ("%lld\n", ans);
return 0;
}