1. 程式人生 > 其它 >2018-2019 ACM-ICPC, Asia East Continent Finals 補題

2018-2019 ACM-ICPC, Asia East Continent Finals 補題

企圖趁著隊友有空的時間練幾場,隊友上來就挑了一場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}\)

的位置攻擊,貢獻為\(\sum (x_{p_k} - i) = \sum x - j * i\)。於是再增加一維,設\(f(i, j, k)\)表示第\(i\)輪結束之後,後面攻擊了\(j\)次,後面攻擊的回合數標號之和為\(k\)的最大傷害,不難寫出\(O(n^4)\)的轉移。

#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的力量戰,惡魔形態是不是太拉了一點……