从题意可知每次操作可以选择一个子序列,在子序列中的下标为奇数的+1或-1,为偶数的-1或+1,问最少需要多少次操作可以把所有数全都变为0
可以贪心地想,最好可以用正负数相互抵消的操作,然后先考虑前面的正数或负数对后面的贡献,先拿正数来说,先累加出所有遍历过的正数的和,这些就是可以抵消多少负数,再考虑如果前面有负数,这个正数能否被抵消?能抵消多少?如果a[i]大于前面负数(取绝对值)的和,说明前面的负数不能完全把a[i]抵消为0,那么需要额外的a[i]-sum2次操作来抵消多余的,把sum2置为0,如果sum2大于等于a[i]说明前面的负数的贡献能抵消掉这个正数,那么sum2-a[i],即还能再抵消多少正数,如果a[i]为负数同理。
AC代码:
#include <bits/stdc++.h>
using namespace std;
using LL = long long;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int T;
cin >> T;
while (T--) {
int n;
cin >> n;
vector<int> a(n + 1);
for (int i = 1; i <= n; i++) {
cin >> a[i];
}
LL sum1 = 0, sum2 = 0, ans = 0;
for (int i = 1; i <= n; i++) {
if (a[i] == 0) {
continue;
} else if (a[i] > 0) {
sum1 += a[i];
if (a[i] > sum2) {
ans += a[i] - sum2;
sum2 = 0;
} else {
sum2 -= a[i];
}
} else {
sum2 += -a[i];
if (-a[i] > sum1) {
ans += -a[i] - sum1;
sum1 = 0;
} else {
sum1 += a[i];
}
}
}
cout << ans << '\n';
}
return 0;
}