AGC018C Coins 题解

模拟费用流。

传送门

题意:共 n=x+y+z 个人,每个人可以选择获得 ai 个金币或 bi 个银币或 ci 个铜币。要选 x 个人拿金币,y 个人拿银币,z 个人拿铜币。问币数总和最大是多少。n105

先建出费用流模型:把一个人的选择视作一个人流到了金币/银币/铜币的对应点。

给每个人抽象出一个点 pi,金银铜币抽象出三个点 g,s,b,以及超源点 S 和超汇点 T
Spi,容量 1 费用 0g,s,bT,容量 1 费用 0

pig,s,b,容量 1,费用 ai/bi/ci

我们观察发现,这个费用流模型本质不同的增广路有十几种,根据经过 g,s,b 中的几个点分类讨论可以得出。直接模拟当然也可以,但是太复杂了,要考虑简化。
让每个人先取金币,令 Bi=biai,Ci=ciai。则只要在 n 个人中选 y 个人取 Biz 个人取 Ci 即可。费用流模型还是类似上面,但是右边就只剩两个点了。

这时本质不同的增广路就只剩四种:

  • SpisT。这种的收益是 Bi

  • SpibT。这种的收益是 Ci

  • SpispjbT。这种就是让一个已经选了 Cjj 转而选 Bj,收益是 Ci+BjCj

  • SpibpjsT。这种的收益是 Bi+CjBj

开四个堆分别维护即可。但鉴于这题调了 2.5h 且非常经典,所以再具体一点。

开四个堆 h1,h2,h3,h4

h1 维护当前还未决定选 Bi 还是选 Ci的人中 Bi 的最大值及其编号h2 维护还未决定的人中 Ci 的最大值及其编号。

h3 维护所有目前选了 Ci 的人中 BiCi 的最大值及其编号。h4 维护所有目前选了 Bi 的人中 CiBi 的最大值及其编号。

:虽然上面的收益是 Ci+BjCj,但是一定不要让 h3h4 维护 Ci+BjCj 的最大值和对应的 i,j。第一是难写,第二是复杂度不对。

当我们想应用后两条增广路的时候,可以用 h2,3 的堆顶共同求出 Ci+BjCj 的最大值。

依次考虑应用每种增广路后会新增的影响。

这里一定要明确一下每种增广路对应的实际意义。

  • 应用 h1 的堆顶:对应把某个还没选的选为 Bi

  • 应用 h2 的堆顶:对应把某个还没选的选为 Ci

  • 应用 h3+h2 的堆顶:对应把某个还没选的选为 Ci,然后把一个已经选为 Bj 的改成 Cj

  • 应用 h4+h1 的堆顶:对应把某个还没选的选为 Bi,然后把一个已经选为 Cj 的改成 Bj

然后看每种增广路带来的可能性。

  • 应用 h1 的堆顶:把某个还没选的选为 Bi,会增加 h3 的把某个 Bj 改成 Cj 的可能性。

  • 应用 h2 的堆顶:把某个还没选的选为 Ci,会增加 h4 的把某个 Cj 改成 Bj 的可能性。

  • 应用 h3+h2 的堆顶:把某个还没选的选为 Ci,然后把一个已经选为 Bj 的改成 Cj。这种操作会新增一个 Bi 和一个 Ci,也就是说 h3,h4 的可能性都会增加。

  • 应用 h4+h1 的堆顶:把某个还没选的选为 Bi,然后把一个已经选为 Cj 的改成 Bj。与 h3 的类似。

最后还要注意一下:为了保证每次取出的堆顶都是有效的,在每次取堆顶之前,把 h1,h2 的所有在堆顶的已经选好了的元素都 pop 掉。

这里需要 pop 的原因是:在应用 h3,h4 的时候,会同时使用 h1,h2 的堆顶。(当然,在应用 h3,h4 的时候,顺便把额外使用的堆顶也 pop 掉同样可以)

h3h4 不需要 pop 的原因是没有任何一种增广路在应用时,会把 h3,h4 作为额外使用的堆顶。

顺路一提,这题有一个简化版CF730I:Olympiad in Programming and Sports

posted @   FLY_lai  阅读(27)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示