[JOI Open 2024] 中暑

zhouhuanyi發表於2024-06-19

原問題的規則實際上很大程度上是為最小化而設計的,但是我們卻要求的是最大化,這意味著原問題的規則實際上是與我們要最最佳化的問題相矛盾,可行的辦法可能是透過一些轉化使新問題與規則剛好契合。

考慮原問題的規則實際上告訴我們只有當兩邊都不能放的時候才會對答案產生貢獻,意味著實際上最最佳化的其實是儘可能製造兩邊都滿的位置,第 \(i\) 條路上的人會產生貢獻當且僅當 \(i\)\(i+1\) 都被放滿。

實際上可以發現這樣的轉化是非常好的,如果我們無視一個位置放滿了就不能再被放的限制,問題的結果不會發生改變,這是因為如果一個位置放滿了再繼續放,這樣不如放一個沒有放滿的位置,這樣會使位置變得更加滿從而使得答案儘可能的最大化。這意味著原問題的規則在轉化問題中就是用來最大化,這是非常契合的。

考慮如果確定好了每一個位置被佔據的時間 \(t_{i}\),則第 \(i\) 條道路上的人會產生貢獻當且僅當其到達時間比 \(\max(t_{i},t_{i+1})\) 要大。這樣如果 \(t\) 序列確定,答案也就確定了。

考慮怎樣的 \(t\) 序列是合法的,對於每一個位置 \(i\),要求在 \(t_{i}\) 之前第 \(i-1\)\(i\) 的道路佔據 \(i\) 的大於等於 \(C_{i}\) 個。這實際上是一個匹配問題,使用霍爾定理後實際上變為判定對於一個位置集合 \(S\),其鄰域 \(N(S)\) 的人數都要大於等於 \(S\) 集合的 \(C\) 之和。

考慮如果 \(S\) 是若干段連續的區間且 \(S\) 不合法,那麼根據抽屜原理至少有一段區間滿足其也不合法,所以實際上只需要判定區間即可。實際上可以歸約為最小子段和,可以簡單 \(\text{dp}\) 判定。

那麼實際上只需要 \(\text{dp}\) 一個 \(t\) 序列,內層 \(\text{dp}\) 級記錄一下最小字尾和,判定其是否時刻 \(\geqslant 0\) 即可。由於每個位置 \(i\) 取到的 \(t\) 的集合 \(T_{i}\),只會在相鄰的兩條道路上的人的到達時刻(特別,最後的一個時刻要置為極大值)與 \(0\) 處取到,所以 \(\sum_{i=1}^{n} T_{i}\)\(O(n)\) 級別的。而每個點 \(i\) 只需保留 \(T_{i}\) 個時間,每個時間保留 \(T_{i}\) 個最小字尾和,轉移到 \(T_{i+1}\) 個狀態,複雜度為 \(O(\sum_{i=1}^{L-1}T_{i}^2T_{i+1})=O(n^3)\) 的。但出題人沒有刻意卡所以可以拿到 \(95\) 分。

實際上如果事先將取到極大值的最後一個時刻忽略,每一個轉移可以拆成一段字首向一個點和一段字尾向一個點的轉移,取前字尾 \(\text{max}\) 即可變成 \(O(\sum_{i=1}^{L}T_{i}^2+\sum_{i=1}^{L-1}T_{i-1}T_{i})=O(n^2)\),常數很小,速度很快。

相關文章