1. 程式人生 > 實用技巧 >Codeforces Round #668 (Div. 2) B. Array Cancellation (思維,貪心)

Codeforces Round #668 (Div. 2) B. Array Cancellation (思維,貪心)

  • 題意:有一個長度為\(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;
    }