Codeforces Round #723 (Div. 2) C2. Potions (决策反悔)

题意:

给出一个数组a,一开始生命值为0,然后从1至n依次决定生命值是否加上 a [ i ] a[i] a[i] ,要保证在这个过程中生命值不能为负数,求最多能加多少个数。

题解:

感觉还是挺妙的一个题。

当遇到 ≥ 0 \geq0 0 的数,肯定是要选的。

当遇到负数,假如加上去生命值不为负,我们可以先将其加上去,并将其放入到优先队列中。假如加上去生命值为负数,那么就得考虑是否可以去掉前面已选的一个负数然后加上这个数。这就是优先队列的作用,我们取队列里最小的值和当前的数比较,如果当前数大,那么此时就可以反悔,不要前面的那个数,选择当前数。

可以发现,后悔的过程并不影响选的数的个数,所以这种贪心做法是正确的。

代码:

#pragma GCC diagnostic error "-std=c++11"
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
#include<map>
#include<stack>
#include<set>
#include<ctime>
#define iss ios::sync_with_stdio(false)
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
typedef pair<int,int> pii;
const int mod=1e9+7;
const int MAXN=2e5+5;
const int inf=0x3f3f3f3f;
int main()
{
    int n;
    cin>>n;
    priority_queue<int>q;
    ll s=0;
    int ans=0;
    for(int i=1;i<=n;i++)
    {
        int x;
        cin>>x;
        if(s+x>=0)
        {
            ans++;
            s+=x;
            if(x<0) q.push(-x);
        }
        else
        {
            if(!q.empty()&&-x<q.top())
            {
                s+=x+q.top();
                q.pop();
                q.push(-x);
            }
        }
    }
    cout<<ans<<endl;
}
posted @ 2021-06-01 00:23  TheBestQAQ  阅读(39)  评论(0)    收藏  举报