11.20 CW 模擬賽 T3.貨物分組

Yorg發表於2024-11-21

演算法

考慮 \(\rm{dp}\)

\(f_{i, j}\) 表示前 \(i\) 個數中, 分成 \(m\) 組的最小花費
關於轉移, 我們有

\[f_{i, j} = \min(f_{k, j - 1} + j \times \rm{Sum}(k + 1, i) + \max(k + 1, i) - \min(k + 1, i)) \]

其中 \(\rm{Sum}\) 可以字首和預處理, \(\max, \min\) 可以 \(\rm{ST}\) 表預處理

這樣轉移是 \(\mathcal{O} (n ^ 3)\) 的, 考慮最佳化

這裡是一個 \(\rm{trick}\) , 即費用提前計算, 題面中花費 \(i \times w_{sum}\) 轉化成每一次的花費都是 $ \rm{Sum}(i + 1, n)$

\(\rm{dp}\) 柿子轉化成 \(dp_i = \min \left[dp_j + Sum(j + 1, n) + \max(j + 1, i) - \min(j + 1, i))\right]\)

複雜度 \(\mathcal{O}(n ^ 2)\) , 考慮最佳化轉移

對於 \(Sum(j + 1, n)\) 是定值, 我們考慮將其提出

方程轉化成 \(dp_i = Sum(j + 1, n) + \min \left[dp_j + \max(j + 1, i) - \min(j + 1, i))\right]\)

我們必須要最佳化轉移

考慮令 \(g_j = dp_j + \max(j + 1, i) - \min(j + 1, i))\) , 維護 \(g_j\) 最小值

這是可以維護的嗎?

考慮線段樹維護 \(g\) ,

對於每一次更新 \(dp_i\)

我們可以在單調棧中找到區間最大值小於 \(a_i\) 最小的 \(j\) , 顯然的, \(j \sim i\) 這一段中, 區間最大值都需要更新
區間最小值同理

於是我們只需要維護區間最值 and 區間加法

程式碼

總結

費用提前計算是一個巧妙的 \(\rm{trick}\)

注意 \(\rm{dp}\) 不能僅僅簡單的省略掉一維, 很有可能會導致正確性出現問題, 這個多練練應該可以解決

對於神秘轉移式子, 考慮多來幾種資料結構維護