-
LOJ P507
-
有 \(n\) 張牌排成一排,每張牌有屬性 \((c_i, v_i)\)。保證 \(c_i \le k\)。
每次操作選擇兩張牌 \(l, r\) 滿足 \(c_l = c_r\),刪除 \(l \sim r\) 中的所有牌,並獲得 \(\sum_{i=l}^rv_i\) 的收益。
求最大的收益。
-
\(n, k \le 10^6\)。
設狀態 \(f_i\) 表示若只考慮前 \(i\) 張牌,能獲得的最大收益。
轉移列舉第 \(i\) 張牌是否是在最後一次操作中被刪,以及被哪個區間刪。即 \(f_{i - 1}\) 和 \(\max_{j=1}^{i - 1}\{f_{j - 1} + \sum_{k=j}^iv_k \mid c_i = c_j\}\) 的較大值。
直接做是 \(n^3\) 的。區間求和那個部分可以字首和最佳化,但仍然是 \(n^2\) 的,即 \(\max_{j=1}^{i - 1}\{f_{j - 1} + \sum_{k=1}^iv_k - \sum_{k=1}^{j-1}v_k \mid c_i = c_j\}\)。
可以把與 \(j\) 無關的提到外面,即 \(\sum_{k=1}^iv_k + \max_{j=1}^{i - 1}\{f_{j - 1} - \sum_{k=1}^{j-1}v_k \mid c_i = c_j\}\)。
然後這個就很好維護了。我們用桶維護每個 \(c_i\) 所對應的最大的 \(f_{i-1} - \sum_{k=1}^{i-1}v_k\),轉移可以最佳化成 \(\Theta(1)\)。總時間複雜度 \(\Theta(n)\)。
-
P4342 [IOI1998] Polygon
-
有一個 \(n\) 個頂點 \(n\) 條邊的環,頂點上有數字,邊上有 \(+, \times\) 兩種運算子號。
首先刪掉一條邊,然後每次選擇一條連線 \(V_1, V_2\) 的邊,用邊上的運算子計算 \(V_1\) 和 \(V_2\) 得到的結果來替換這兩個頂點。
求最後元素的最大值。
-
\(n \le 50\)。
顯然區間 DP。首先倍長破環為鏈。
設狀態 \(f_{l, r}\) 表示將區間 \(l \sim r\) 內的數字處理後得到的最大數字。轉移列舉斷點 \(k\),即 \(f_{l, r} = \max_{k=l}^{r-1} \operatorname{opt}(f_{l, k}, f_{k + 1, r})\),其中 \(\operatorname{opt}\) 表示邊上的運算子號。
這樣做是不正確的。注意到兩個負數相乘結果為正數,所以再維護 \(g_{l, r}\) 表示最小值。轉移類似。
複雜度 \(\Theta(n^3)\)。