题意:有一个长度为\(n\)并且所有元素和为\(0\)的序列,你可以使\(a_{i}-1\)并且\(a_{j}+1\),如果\(i<j\),那么这步操作就是免费的,否则需要花费一次操作,问最少操作多少次使得所有元素为\(0\).
题解:首先优先考虑不用花费的情况,如果\(a_{i}>0\),\(a_{j}<0\),且\(i<j\),那么我们可以免费的使这两个或一个元素变为\(0\),这里我们可以倒着遍历,记录负数的和,如果遇到正数就抵消,如果不足以抵消正数,那么该位置剩余的正数值就要贡献给答案.具体细节看代码.
代码:
int t;
int n;
ll a[N];
int main() {
//ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
t=read();
while(t--){
n=read();
for(int i=1;i<=n;++i){
a[i]=read();
}
ll cnt=0;
ll ans=0;
for(int i=n;i>=1;--i){
if(a[i]<0){
cnt+=a[i];
}
else{
ans+=max((ll)0,a[i]+cnt);
cnt=min((ll)0,a[i]+cnt);
}
}
printf("%lld\n",ans);
}
return 0;
}
Codeforces Round #668 (Div. 2) B. Array Cancellation (思维,贪心)
原文:https://www.cnblogs.com/lr599909928/p/13657907.html