思路
计算前缀和,先看是否存在前缀和小于0的位置。
如果存在,说明我们至少需要放弃一个点。
则从这前缀中,找出最小下标,标记为无穷小(这个点,可以做为后边其他负数点的左边界。)
接下来就清晰了。
由于操作数有限,从所有的负数点中,贪心地取最小的,即可。
代码
#include<bits/stdc++.h>
using namespace std;
#define endl '\n';
typedef long long LL;
void solve(){
LL n,k,res = 0;
cin >> n >> k;
vector<LL> a(n + 1),s(n + 1);
for(int i = 1;i <= n;i++){
cin >> a[i];
s[i] = s[i - 1] + a[i];
res += (a[i] >= 0);
}
int pos = -1;
for(pos = 1;pos <= n;pos++){
if(s[pos] < 0){
pos = min_element(a.begin() + 1,a.begin() + pos + 1) - a.begin();
a[pos] = -1e18;
break;
}
}
vector<LL> b;
for(int i = 1;i <= n;i++){
if(a[i] < 0)b.push_back(-a[i]);
}
sort(b.begin(),b.end());
for(int i = 0;i < b.size();i++){
if(k - b[i] >= 0){
k -= b[i];
res++;
}
else break;
}
cout << res << endl;
}
int main(){
ios::sync_with_stdio(false);
cin.tie(NULL),cout.tie(NULL);
int t = 1;
//cin >> t;
while(t--){
solve();
}
return 0;
}