meaning of the title
Sol
It's like the first time I've been exposed to ternary pressure
First of all, it's not necessarily the best to eat gems after each fight, because there are imitation monsters, maybe you can hit GG after you finish eating gems with him..
So there are three states that we need to maintain
0: no fight
1: I beat the monster and didn't eat the gem
2: Beat the monster and eat the gem
If we can know that we hit those monsters and ate those gems, then the state at this time will be determined and preprocessed
Then DP will do
The card constant of mdzz
/* It's not necessarily the best way to eat gems after the first fight So we need to name the state of each monster 0: Not hit 1: I beat the monster and didn't eat the gem 2: Beat the monster and eat the gem If we can know that we hit those monsters and ate those gems, then the state at this time will be determined */ #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<map> #include<vector> #include<set> #include<queue> #include<cmath> //#define int long long #define getchar() (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1<<22, stdin), p1 == p2) ? EOF : *p1++) char buf[(1 << 22)], *p1 = buf, *p2 = buf; #define LL long long using namespace std; const int MAXN = 2 * 1e6 + 10; inline int read() { char c = getchar(); int x = 0, f = 1; while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();} while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar(); return x * f; } int T, N; int lim, Hp, A, F, M, Mp[MAXN], IA[MAXN], IF[MAXN], IM[MAXN];//Attack HP defense magic defense LL f[MAXN], Po[16]; struct Enemy { int H, A, D, S, ap, dp, mp, hp; }a[15]; vector<int> v[16]; void init() { memset(f, 0, sizeof(f)); Hp = read(); A = read(); F = read(); M = read(); N = read(); lim = Po[N]; for(int i = 1; i <= N; i++) { a[i].H = read(); a[i].A = read(); a[i].D = read(); a[i].S = read(); a[i].ap = read(); a[i].dp = read(); a[i].mp = read(); a[i].hp = read(); } int K = read(); for(int i = 1; i <= N; i++) v[i].clear(); for(int i = 1; i <= K; i++) { int u = read(), vv = read(); v[vv].push_back(u); } } LL Attack(int sta, int id) { LL Now = f[sta], A = IA[sta], D = IF[sta], M = IM[sta]; LL s = a[id].S, h = a[id].H, aa = a[id].A, d = a[id].D; if (s & 8) aa = A, d = D; // imitate if (s & 2) D = 0; // Defying defense LL AA = max(0ll, A - d); // Warrior deals damage aa = max(0ll, aa - D) * (((s >> 2) & 1) + 1); // Attack power caused by monsters, whether to attack continuously if (AA == 0) return 0; LL t1 = (h - 1) / AA + 1; // How many times do I need to fight LL t2 = (s & 1) ? (t1 * aa) : ((t1 - 1) * aa); // Attack power caused by monsters, whether there is a preemptive attack LL t3 = max(0ll, t2 - M); // Minus magic defense return max(0ll, Now - t3); } void solve() { f[0] = Hp; for(int sta = 0; sta < lim; sta++) { IA[sta] = A; IF[sta] = F; IM[sta] = M; for(int i = 1; i <= N; i++) if(sta / Po[i - 1] % 3 == 2) IA[sta] += a[i].ap, IF[sta] += a[i].dp, IM[sta] += a[i].mp; } for(int sta = 0; sta < lim; sta++) { if(f[sta] == 0) continue; for(int i = 1; i <= N; i++) { if(sta / Po[i - 1] % 3 == 0) {// not kill bool flag = 0; for(int j = 0; j < v[i].size(); j++) if(sta / Po[v[i][j] - 1] % 3 == 0) // not kiil {flag = 1; break;} if(flag == 1) continue; LL nhp = Attack(sta, i); if(nhp > 0) f[sta + Po[i - 1]] = max(f[sta + Po[i - 1]], nhp); } else if(sta / Po[i - 1] % 3 == 1) { f[sta + Po[i - 1]] = max(f[sta + Po[i - 1]], f[sta] + a[i].hp); } } } printf("%lld\n", f[lim - 1] == 0 ? -1 : f[lim - 1]); } main() { Po[0] = 1; for(int i = 1; i <= 15; i++) Po[i] = 3 * Po[i - 1]; T = read(); while(T--) { init(); solve(); } return 0; } /* 2 2 1 1 1 2 1 1 */