本文最后更新于 2024-04-02T19:28:20+08:00
Luogu
分析
这道题要求将一个数组分成若干个非空的子数组,然后计算每个子数组的和,并用每个子数组的和乘以子数组的长度,最后求和。问题的关键在于找到一种分割方式,使得其值最大。
观察发现,我们需要在数组中找到一个位置,将数组分为两个部分,使得右半部分的和尽可能大。对于这个问题,从数组的末尾开始往前遍历是一个比较自然的想法。我们可以维护一个变量 $res$,表示当前遍历到的位置右侧的子数组的和,同时维护一个变量 $sum$,表示值的累加和。每次遍历到一个位置,都更新 $res$,并判断如果 $res$ 大于 $0$ 或者已经遍历到数组的开头,就将 $res$ 累加到 $sum$ 中。最终,$sum$ 即为所求的值。
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| #include<bits/stdc++.h> using namespace std; typedef long long ll; const int N=1e5+10; ll a[N];
int main() { int t; cin>>t; while(t--) { int n; cin>>n; for(int i=0;i<n;i++) cin>>a[i];
ll sum=0, res=0;
for(int i=n-1; i>=0; i--) { res += a[i]; if(res > 0 || i == 0) sum += res; }
cout<<sum<<endl; }
return 0; }
|