ABC320 FG

F - Fuel Round Trip

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

fi,j,k 表示到第 i 个加油站,来程加油后油量为 j,回程加油后油量为 k 的最小代价。

初始对于 0ih,有 f0,h,i=0

考虑刷表法转移(ii+1),令 d=xi+1xi,然后根据在哪一段路程加油分类讨论:

  • 不加油:

fi+1,jd,k+dfi,j,k

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

fi+1,min(jd+Fi+1,h),k+dfi,j,k+pi+1

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

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

    fi,j,k 表示到第 i 个加油站,来程加油后油量为 j,回程加油前油量为 k 的最小代价。

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

fi+1,jd,kfi,j,min(k+Fi+1,H)d+pi+1

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

这样最后的答案就是 mini=0hfn,i,i

时间复杂度 O(n3)

Code

G - Slot Strategy 2 (Hard)

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

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

以每一行为左部点,下标为右部点。对于每一行 i,如果 si,j=djt,那么连边 AiBj,然后检查是否存在完美匹配即可。

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

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

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

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

Code

posted @   Southern_Dynasty  阅读(4)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
点击右上角即可分享
微信分享提示