ABC320 FG

F - Fuel Round Trip

注意到路程分成了两段,所以我们也按两段 dp。

\(f_{i,j,k}\) 表示到第 \(i\) 个加油站,来程加油后油量为 \(j\),回程加油后油量为 \(k\) 的最小代价。

初始对于 \(0\le i\le h\),有 \(f_{0,h,i}=0\)

考虑刷表法转移(\(i\to i+1\)),令 \(d=x_{i+1}-x_i\),然后根据在哪一段路程加油分类讨论:

  • 不加油:

\[f_{i+1,j-d,k+d}\leftarrow f_{i,j,k} \]

需要满足 $j-d\ge 0$ 且 $k+d\le h$。
  • 来程时加油:

\[f_{i+1,\min(j-d+F_{i+1},h),k+d}\leftarrow f_{i,j,k}+p_{i+1} \]

需要满足 $j-d\ge 0$ 且 $k+d\le h$。
  • 回程时加油:

    ……此时发现不太好搞,如果直接枚举容量,那么我们无法判断加油前的容量是多少。于是我们修改状态的定义:

    \(f_{i,j,k}\) 表示到第 \(i\) 个加油站,来程加油后油量为 \(j\),回程加油前油量为 \(k\) 的最小代价。

    这样前面的转移,初始条件都不变。然后就很好转移了,枚举 \(i+1\) 处的返程容量 \(k\),那么:

\[f_{i+1,j-d,k}\leftarrow f_{i,j,\min(k+F_{i+1},H)-d}+p_{i+1} \]

需要满足 $j-d\ge 0$ 且 $\min(k+F_{i+1},H)\ge 0$。

这样最后的答案就是 \(\min_{i=0}^{h}f_{n,i,i}\)

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

Code

G - Slot Strategy 2 (Hard)

考虑枚举最终字符 \(d\),然后二分判定。

假设当前时间为 \(t\),那么对于每一行,下标在 \([1,t]\) 内值为 \(d\) 的位置都可以选。由于每个位置只能被一行选中,那么可以转换为一个二分图匹配问题:

以每一行为左部点,下标为右部点。对于每一行 \(i\),如果 \(s_{i,j}=d\)\(j\le t\),那么连边 \(A_{i}\to B_{j}\),然后检查是否存在完美匹配即可。

这里需要注意一点,由于每个时间不能重复选,所以 \(t\) 最大会到 \(n\times m\) 级别,这需要我们隐式地将字符串 copy \(n\) 次。而且,此时二分图的点数和边数都是 \(O(nm)\) 级别,无法通过。

但是左部点数量很少,由 Hall 定理我们可以知道,只要满足 \(|T|\le |N_G(T)|\) 就一定存在完美匹配。因此对于每个左部点,只需要连出去 \(n\) 条边即可。

这样点数和边数就都降到了 \(O(n^2)\) 级别。总的时间复杂度是 \(O(n^3d\log(nm))\),就能过了。其中 \(d=10\)

实现时我用了 map 给右部点标号,所以还要多个 \(\log\),但是跑不满,所以能过。

Code

posted @ 2024-02-28 15:04  Southern_Dynasty  阅读(3)  评论(0编辑  收藏  举报