题解 P10055【[CCO2022] Rainy Markets】

首先尽量把所有人放在左边的车站,然后再尽量放在右边的车站,求出此时 \(i\) 位置车站有多少空位留给 \(i+0.5\) 位置的人,记为 \(f_i\)。也就是:

\[f_i\gets\max\{b_i-\max\{p_{i-1}-f_{i-1},0\},0\} \]

然后从右向左贪心。对于第 \(i+0.5\) 位置的人,设去左边、不动买伞、去右边的人数分别为 \(l_i,m_i,r_i\)。由于右侧都已经尽量优地分配过,令这个位置的人优先去右边不会使得情况变得更劣,因此先贪心把右边填满,也就是:

\[\begin{aligned} r_i&\gets\min\{b_{i+1}-l_{i+1},p_i\}\\ p_i&\stackrel{-}{\gets}r_i \end{aligned} \]

之后为了使总花费尽量小,肯定是在不影响左侧的情况下尽量都去左边,这时候计算过的 \(f_i\) 就派上了用场,\(f_i\) 就代表着左边有多少地方一定可以给 \(i+0.5\) 位置的人,且不会影响左侧的决策,也就是:

\[\begin{aligned} l_i&\gets\min\{f_i,p_i\}\\ p_i&\stackrel{-}{\gets}l_i \end{aligned} \]

剩下的人一定需要买伞,因为即使在这里不买伞,去到左边也会使得左边的一些人需要买伞。我们让他们直接就地买伞:

\[\begin{aligned} m_i&\gets\min\{u_i,p_i\}\\ p_i&\stackrel{-}{\gets}m_i\\ ans&\stackrel{+}{\gets}m_i \end{aligned} \]

如果还有剩下的人,就不得不让他们去左边挤一挤了:

\[l_i\stackrel{+}{\gets}p_i \]

如果 \(l_i > b_i\) 即为无解,所有 \(l_i\le b_i\) 即求得了最优解及其构造。

时间复杂度 \(O(n)\)

所有关键都在上文给出了,代码就不放了。

posted @ 2024-01-08 19:23  rui_er  阅读(9)  评论(0编辑  收藏  举报