hello_world_djh

orz

关注我

CF1749B Death's Blessing 题解

本蒟蒻第一次发CF题解,好兴奋啊

题目传送门:CF1749B Death's Blessing

这个题最难处理的明显是 b 数组对邻居的影响,我们可以注意到题目中有这样一句话

注意,第 1 个和第 n 个不相邻

这样,我们就可以想出我们的贪心策略之一:从两边选。因为只要不从两边选,他对最终值的影响就会翻倍,从两边选的影响就是一倍。

通过说明和提示我们发现这句话:

In the first test case, there is only one monster that will be killed in 1010 seconds.

我们就可以想到我们的贪心思路之二:每次选两边的较小者。因为我们可以发现最后一个选的不算影响,所以我们可以贪心的将最大值留到最后去选。

此题的贪心思路是固定的,但却有两种写法。有一种就是第一个写题解的大佬和我的一个同机房大佬的写法一样,我们可以从这个思路得出:最大值没有贡献,其他值一倍贡献,所以就在输入时将 a 和 b 的和统计出来,在减去最大的 b 即可。

还可以像本蒟蒻考场时这样,用双指针模拟贪心思路选数的过程,\(O(n)\) 扫一遍,最终复杂度与 \(O(n)\) 同阶,但空间复杂度稍差,是 \(O(N)\) 的。

废话少说,上代码:

点击查看代码
#include <bits/stdc++.h>

template <typename T> T read() {
    T x = 0, f = 1; char ch = getchar();
    for (; ch < '0' || ch > '9'; ch = getchar()) if (ch == '-') f = ~f + 1;
    for (; ch >= '0' && ch <= '9'; ch = getchar()) x = (x << 3) + (x << 1) + (ch ^ '0');
    return x * f;
}

long long a[int(2e5 + 10)], b[int(2e5 + 10)];

int main() {
    int T = read<int>();
    while (T--) {
        int n = read<int>();
        for (int i = 1; i <= n; i++) a[i] = read<int>();
        for (int i = 1; i <= n; i++) b[i] = read<int>();
        int p = 1, q = n; long long ans = 0;
        for (int i = 1; i < n; i++) {
            if (b[p] < b[q]) {
                ans += a[p]; a[p + 1] += b[p]; p++;
            }
            else {
                ans += a[q]; a[q - 1] += b[q]; q--;
            }
        }
        ans += a[p]; printf("%lld\n", ans);
    } return 0;
}

完结撒花!!!

posted @ 2022-10-26 17:43  hello_world_djh  阅读(69)  评论(0)    收藏  举报