CF1396C Monster Invaders
CF1396C Monster Invaders
建议不要看中文,直接看英文题面,里面有很重要的一句话:一开始都没有装弹,一次只能装一把枪。
这个东西决定了我们贪心的方案,不然的话可能像我以前或者一开始一样当成同时开始冷却 /qd
这边再吐槽一下,之前已知不会订正,现在想想还是挺简单的。
因为 $r_1 \le r_2 \le r_3$。
首先考虑总共只有 $3$ 种打的方案:
- $a_i \times r_1 + r_3$。
- $a_i \times r_1 + r_1 + r_1$。
- $r_2 + r_1$。
而且考虑走的方法,我们会考虑一开始直接走到头,之后一次回来,发现距离是 $2d$。
我们考虑相邻两个一起搞定,那么乍一看是 $3d$ 但是每两个相邻之间本质上只有 $d$,均摊一下还是 $2d$。
所以我们只需要考虑相邻的部分,直接考虑当前是否打死,设 $f(i, 0/1)$ 表示当前考虑到位置 $i$,$\tt boss$ 还有血量 $0/1$ 的最小代价。
直接分类讨论暴力转移即可。
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 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
| #include <bits/stdc++.h> using namespace std;
namespace Legendgod {
namespace Read {
#ifdef Fread const int Siz = (1 << 21) + 5; char buf[Siz], *iS, *iT; #define gc() (iS == iT ? (iT = (iS = buf) + fread(buf, 1, Siz, stdin), iT == iS ? EOF : *iS ++ ) : *iS ++) #define getchar gc #endif
template <typename T> void r1(T &x) { x = 0; int f(1); char c(getchar()); for(; !isdigit(c); c = getchar()) if(c == '-') f = -1; for(; isdigit(c); c = getchar()) x = (x * 10) + (c ^ 48); x *= f; } template <typename T, typename...Args> void r1(T &x, Args&...arg) { r1(x), r1(arg...); }
}
using namespace Read;
const int maxn = 1e6 + 5; typedef long long int64; int64 f[maxn][2]; int64 r[4], d, a[maxn]; int n;
signed main() { int i, j; r1(n, r[1], r[2], r[3], d); for(i = 1; i <= n; ++ i) r1(a[i]); memset(f, 0x3f, sizeof(f)); f[1][0] = r[1] * a[1] + r[3]; f[1][1] = min(r[2], r[1] * a[1] + r[1]); function<void(int64 &x, const int64 &c)> Upd; Upd = [&](int64 &x, const int64 &c) { x < c ? 0 : x = c; }; for(i = 1; i < n; ++ i) { Upd(f[i + 1][0], f[i][0] + d + a[i + 1] * r[1] + r[3]); Upd(f[i + 1][1], f[i][0] + d + min(a[i + 1] * r[1] + r[1], r[2])); Upd(f[i + 1][1], f[i][1] + d + a[i + 1] * r[1] + r[1] + 2 * d + r[1]); Upd(f[i + 1][1], f[i][1] + d + r[2] + 2 * d + r[1]); Upd(f[i + 1][0], f[i][1] + d + a[i + 1] * r[1] + r[3] + 2 * d + r[1]); Upd(f[i + 1][0], f[i][1] + d + a[i + 1] * r[1] + r[1] + 2 * d + r[1] + r[1]); Upd(f[i + 1][0], f[i][1] + d + r[2] + 2 * d + r[1] + r[1]); if(i == n - 1) { Upd(f[i + 1][0], f[i][1] + d + a[i + 1] * r[1] + r[3] + d + r[1]); } } printf("%lld\n", f[n][0]); return 0; }
}
signed main() { return Legendgod::main(), 0; }
|