20240918:DP選做

Lu_xZ發表於2024-09-18

本文為 @A_zjzj《dp 專題》學習筆記。

轉移性質

Lanterns

題意:\(n\) 個燈籠拍成一排,第 \(i\) 個燈籠具有 \(p_i\) 的亮度。每個燈籠要麼朝向左照亮 \([i - p_i, i - 1]\),要麼朝向右照亮 \([i + 1, i + p_i]\)

尋找一種方案,為所有的燈籠定向,使得每一個燈籠被至少一個其他燈籠照亮。\(2 \le n \le 3\times 10^5, p_i \in [0, n]\)

\(f_i\) 表示前 \(i\) 盞燈能覆蓋的最長字首,考慮幾種轉移:

  • \(i - 1\) 盞燈能覆蓋 \(i\)\(f_i \gets \max(f_{i - 1}, i + p_i)\)
  • \(i - 1\) 盞燈不能覆蓋 \(i\),先把 \(i\) 忽略,之後再定向,\(f_i \gets f_{i - 1}\)
  • \(i\) 向左覆蓋,存在一個 \(f_j + 1 \ge i - p_i\),所有 \((j, i)\) 的燈向右定向,\(f_i \gets \max(i - 1,\ j + 1 + p_{j + 1}, \cdots, i - 1 + p_{i - 1})\)

顯然有 \(f_{i - 1} \le f_i\),二分 \(j\),樹狀陣列維護字尾最大值。submission

來源不明的一道題

題意:給出 \(n\)\(a_{2 \sim n}, b_{2 \sim n}\),表示 \(i\) 有單向邊連向 \([a_i, i - 1]\)\([b_i, i - 1]\) 有單向邊連向 \(i\),邊權為 \(1\)

\(d(i, j)\) 表示 \(i\)\(j\) 的最短路,求 \(\bigoplus_{i, j} d(i,j) \times (i + j)\)\(1\le n\le 6000,\ a_i < i,\ b_i < i,\ \text{1s}\)

如果從 \(i\) 向左走一步到 \(j\),緊跟著向右走到 \(k\),這是一定不優的:

  • \(k \le i\),顯然有 \(a_i \le j < k \le i\),可以一步或零步走到。
  • \(k > i\)\(j\) 能一步到 \(k\),說明 \(b_k \le j\),說明 \(i\) 也能一步到 \(k\)

因此最優方案一定是先向右走若干步,再向左走若干步。

列舉起點 \(s\),設 \(f_i\) 表示 \(s\)\(i\) 的最短路,分兩部分轉移(從前往後掃一遍,再從後往前掃一遍):

第一部分:\(f_i \gets f_j + 1,\ b_i \le j < i\);第二部分:\(f_i \gets f_j + 1,\ a_j \le i < j\)。可以線段樹做到平方對數。

以向右的轉移為例,如果 \(i < j\land f_i \ge f_j\)\(f_i\) 顯然不優。

\(g_x = \max_\limits{j < i\land f_j = x} j\),表示值為 \(x\) 時的最優決策點,顯然 \(f_i\) 的上界為 \(x = f_{i - 1} + 1\)。不斷使 \(x \to x - 1\),直到 \(g_{x - 1} < b_i\)

\(x\) 更新 \(f_i\),並使 \(g_x = i\)。上述做法依賴於 \(g_0\sim g_{f_{i - 1}}\) 是單調遞減的,可以歸納證明。勢能增量 \(O(n)\),複雜度 \(O(n)\)

對於向左的轉移,如果 \(a_i \le a_j \land f_i \le f_j\)\(f_j\) 顯然不優。設 \(g_x = \min\limits_{j > i \land f_j = x} a_j\)

\(f_i\) 的上界是 \(\min(f_i, f_{i + 1} + 1)\),不斷使 \(x \to x - 1\),直到 \(g_{x - 1} > i\),歸納證明 \(g_0 \sim g_{f_{i + 1}}\) 是單調遞增的。

時間複雜度 \(O(n^2)\)submission

一類特殊題型

求一個排列 \(\{p\}\),最小(大)化如下值:

\[\sum_{i = 1}^{n - 1} f(p_i, p_{i + 1}) \]

其中 \(f(i, j)\) 如下:

\[\begin{cases} a(i) + b(j) & i > j\\ \\ c(i) + d(j) & i < j \end{cases} \]

考慮按照 \(p_i\) 的大小,從小到大插入序列的過程,維護若干連續段(只是說明某些元素在最終排列上連續,並沒有確定位置)。

每次插入有以下情況:

  • 將兩個連續段合併成一個。
  • 插入一個連續段的左邊/右邊。
  • 新增一個連續段。

由於保證了插入順序,容易算出每個元素的貢獻。另外,需要維護連續段個數,保證最終連續段合併成一個。

可能需要判斷插入時是否插在全域性的開頭或末尾。

Ant Man

題意:給定排列 \(\{p\}\) 的第一個元素 \(s\) 和最後一個元素 \(e\),找出一個排列,最小化:

\[\sum_{i = 1}^{n - 1} \begin{cases} \vert x_i - x_{i + 1}\vert + c_i + b_{i + 1} & p_{i + 1} < p_i\\ \\ \vert x_{i + 1} - x_i\vert + d_i + a_{i + 1} & p_{i + 1} > p_i\\ \end{cases} \]

其中,\(2\le n \le 5000,\ x_1 < x_{2} < \cdots < x_n\)

和原模型基本一致,\(f(i, j)\) 表示插入前 \(i\) 個數,分成 \(j\) 個連續段的最小代價。

注意 \(s, e\) 沒有合併連續段的轉移,\(s\) 只算右邊貢獻,\(e\) 只算左邊貢獻,\(s\) 所在連通塊不能右插,\(e\) 不能左插。

新增一個 \(i\) 作為連通塊時,需要滿足 \(j - [i > s] - [i > e] \ge 1\),否則無法新增。submission

[JOI Open 2016] 摩天大樓

DP構建

Price Combo

DP套DP

[TJOI2018] 遊園會

Bus Analysis

DP技巧

[AGC013D] Piling Up

[BJOI2017] 同構

Mr. Kitayuta's Gift

資料結構最佳化

人造情感(emotion)

[PA2014] Druzyny

細節討論

[POI2013] MUL-Multidrink