[CF1359D] Yet Another Yet Another Task

Description

(l,r) 使得 (sum_{l le i le r} a_i - max_{l le i le r} a_i) 最大化。(|a_i| le 30)

Solution

考虑枚举删除的数的大小 (val),那么现在只有 (a_i le val) 的数才是可用的,这样原序列就被分割成了若干段,选择不能跨段。

假如相邻的两个不可用位置是 (p,q),那么可用区间就是 ([p+1,q-1]),在前缀和序列上的选择位置就是 ([p,q-1])

我们考虑扫描固定一个左端点,右端点不断向右平移,如果累积和小于零则置为 (0),同时不断更新答案,遇到不可用点时,将累积和置为 (0) 并跳过。

#include <bits/stdc++.h>
using namespace std;

int main()
{
    int n;
    cin>>n;

    vector<int> a(n+2);
    for(int i=1;i<=n;i++) cin>>a[i];

    int ans=0;

    for(int val=0;val<=30;val++)
    {
        int sum=0;
        for(int i=1;i<=n;i++)
        {
            if(a[i]>val)
            {
                sum=0;
            }
            else 
            {
                sum+=a[i];
                sum=max(sum,0);
                ans=max(ans,sum-val);
            }
        }        
    }

    cout<<ans<<endl;
}
原文地址:https://www.cnblogs.com/mollnn/p/14081277.html