Codeforces Round #668 (Div. 2) B. Array Cancellation (思維,貪心)
阿新 • • 發佈:2020-09-12
-
題意:有一個長度為\(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; }