CF1526C2

与简单版的思路完全一致,只需要改一下范围。
可以去看我简单版本的博客。

题目简化和分析:

给您一个数组,在其中选择若干个数使得:

  • 任意前缀和 \(\ge 0\)
  • 数量尽可能的大

我们可以使用贪心策略,策略如下:

  • 如果当前数为非负,必喝。
  • 而毒药尽可能的多喝,如果喝没了,就把最小的吐了。

以上操作可以采用优先队列去优化。
重载运算符

struct node{
	ll v;
	bool operator <(const node &x)const{
		return x.v<v;
	}
};

priority_queue<node> q;

既然理解了思路可以动手了。

Solution:

#include<bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef double db;

const int N=2e5+50;
const int M=1e5+50;

inline ll read(){
    ll x=0,f=1;
    char ch=getchar();
    while(ch<'0'||ch>'9'){
        if(ch=='-')
            f=-1;
        ch=getchar();
    }
    while(ch>='0'&&ch<='9'){
        x=(x<<1)+(x<<3)+(ch^48);
        ch=getchar();
    }
    return x*f;
}

ll n;
ll a[N];

struct node{
	ll v;
	bool operator <(const node &x)const{
		return x.v<v;
	}
};

priority_queue<node> q;

int main()
{
	n=read();
	for(int i=1;i<=n;++i) a[i]=read();
	ll ans=n,res=1,cnt=0;
	while(res<=n)
	{
		cnt+=a[res];
		q.push((node){a[res]});
		if(cnt<0){
			node tmp=q.top();
			cnt-=tmp.v;
			q.pop();
			--ans;
		}
		++res;
	}
	printf("%lld\n",ans);	
	return 0;
}
posted @ 2022-09-01 18:30  RVG  阅读(30)  评论(0)    收藏  举报