2018-2019 ACM-ICPC, Asia East Continent Finals 補題
阿新 • • 發佈:2021-10-18
企圖趁著隊友有空的時間練幾場,隊友上來就挑了一場ec-final,只能說與我們的水平不太符合
盡力補題中。
I Misunderstood … Missing
挺有意思的簽到題,一個人還沒想出來。
因為前面的狀態會對後面的狀態產生影響,後面的狀態不會對前面的決策產生影響,所以倒著dp。
考慮將答案組成的形式拆開,設\(f(i, j)\)表示第\(i\)輪結束之後後面還要攻擊\(j\)輪的答案,如果我們進行一個攻擊力\(+b_i\)的操作,後面會有\(jb_i\)的貢獻;如果我們進行一次攻擊,後面會有\(a_i\)的貢獻。
最後考慮這個加差值的操作,如果後面是在\(x_{p_1}, x_{p_2}, \cdots, x_{p_j}\)
#include <bits/stdc++.h> using namespace std; typedef long long ll; typedef double db; typedef pair <int, int> pin; #ifndef ONLINE_JUDGE bool MEMORY_ST; #endif const int N = 105; const int M = 5050 + 5; const ll P = 998244353LL; int T, n; ll a[N], b[N], c[N], f[2][N][M]; namespace Fread { const int L = 1 << 15; char buffer[L], *S, *T; inline char Getchar() { if(S == T) { T = (S = buffer) + fread(buffer, 1, L, stdin); if(S == T) return EOF; } return *S++; } template <class T> inline void read(T &X) { char ch; T op = 1; for(ch = Getchar(); ch > '9' || ch < '0'; ch = Getchar()) if(ch == '-') op = -1; for(X = 0; ch >= '0' && ch <= '9'; ch = Getchar()) X = (X << 1) + (X << 3) + ch - '0'; X *= op; } } using Fread::read; inline void chkMax(ll &x, ll y) { if (y > x) x = y; } #ifndef ONLINE_JUDGE bool MEMORY_ED; #endif int main() { #ifndef ONLINE_JUDGE freopen("sample.in", "r", stdin); clock_t st_clock = clock(); #endif read(T); for (; T--; ) { read(n); for (int i = 1; i <= n; i++) read(a[i]), read(b[i]), read(c[i]); int sum = (n + 1) * n / 2; for (int i = 0; i < 2; i++) for (int j = 0; j <= n; j++) for (int k = 0; k <= sum; k++) f[i][j][k] = -1; f[n & 1][0][0] = 0; for (int i = n; i >= 1; i--) { int cur = i & 1, suc = cur ^ 1; for (int j = 0; j <= n; j++) for (int k = 0; k <= sum; k++) f[suc][j][k] = -1; for (int j = 0; i + j <= n; j++) { for (int k = 0; k <= sum; k++) { if (f[cur][j][k] == -1) continue; chkMax(f[suc][j + 1][k + i], f[cur][j][k] + a[i]); chkMax(f[suc][j][k], f[cur][j][k] + b[i] * (k - i * j)); chkMax(f[suc][j][k], f[cur][j][k] + c[i] * j); } } } ll ans = 0; for (int j = 0; j <= n; j++) for (int k = 0; k <= sum; k++) ans = max(ans, f[0][j][k]); printf("%lld\n", ans); } #ifndef ONLINE_JUDGE clock_t ed_clock = clock(); printf("time = %f ms\n", (double)(ed_clock - st_clock) / CLOCKS_PER_SEC * 1000); printf("memory = %.2f MB\n", (&MEMORY_ED - &MEMORY_ST) / 1024.0 / 1024.0); #endif return 0; }
jls說這就是slay the spire的力量戰,惡魔形態是不是太拉了一點……