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;
}
完结撒花!!!