Codeforces Round #843 (Div. 2) E

文章描述了一种算法问题,其中目标是通过特定操作将所有数变为0。该操作涉及对子序列中的奇偶位置数字加减1。文章提出了一个贪心策略,先累加正数和负数,然后分析正负数之间的抵消关系,以确定最少的操作次数。AC代码示例展示了如何实现这一策略。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

E. The Human Equation

从题意可知每次操作可以选择一个子序列,在子序列中的下标为奇数的+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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值