首页 > 其他分享 >AGC018C Coins 题解

AGC018C Coins 题解

时间:2024-03-25 21:45:02浏览次数:26  
标签:选为 增广 没选 题解 Coins 应用 某个 AGC018C rightarrow

模拟费用流。

传送门

题意:共 \(n=x+y+z\) 个人,每个人可以选择获得 \(a_i\) 个金币或 \(b_i\) 个银币或 \(c_i\) 个铜币。要选 \(x\) 个人拿金币,\(y\) 个人拿银币,\(z\) 个人拿铜币。问币数总和最大是多少。\(n\le 10^5\)。

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

给每个人抽象出一个点 \(p_i\),金银铜币抽象出三个点 \(g,s,b\),以及超源点 \(S\) 和超汇点 \(T\)。
\(S\rightarrow p_i\),容量 \(1\) 费用 \(0\);\(g,s,b\rightarrow T\),容量 \(1\) 费用 \(0\)。

\(p_i\rightarrow g,s,b\),容量 \(1\),费用 \(a_i/b_i/c_i\)。

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

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

  • \(S\rightarrow p_i\rightarrow s\rightarrow T\)。这种的收益是 \(B_i\)。

  • \(S\rightarrow p_i\rightarrow b\rightarrow T\)。这种的收益是 \(C_i\)。

  • \(S\rightarrow p_i\rightarrow s\rightarrow p_j\rightarrow b\rightarrow T\)。这种就是让一个已经选了 \(C_j\) 的 \(j\) 转而选 \(B_j\),收益是 \(C_i+B_j-C_j\)。

  • \(S\rightarrow p_i\rightarrow b\rightarrow p_j\rightarrow s\rightarrow T\)。这种的收益是 \(B_i+C_j-B_j\)。

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

开四个堆 \(h_1,h_2,h_3,h_4\)。

\(h_1\) 维护当前还未决定选 \(B_i\) 还是选 \(C_i\)的人中 \(B_i\) 的最大值及其编号,\(h_2\) 维护还未决定的人中 \(C_i\) 的最大值及其编号。

\(h_3\) 维护所有目前选了 \(C_i\) 的人中 \(B_i-C_i\) 的最大值及其编号。\(h_4\) 维护所有目前选了 \(B_i\) 的人中 \(C_i-B_i\) 的最大值及其编号。

:虽然上面的收益是 \(C_i+B_j-C_j\),但是一定不要让 \(h_3\) 和 \(h_4\) 维护 \(C_i+B_j-C_j\) 的最大值和对应的 \(i,j\)。第一是难写,第二是复杂度不对。

当我们想应用后两条增广路的时候,可以用 \(h_{2,3}\) 的堆顶共同求出 \(C_i+B_j-C_j\) 的最大值。

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

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

  • 应用 \(h_1\) 的堆顶:对应把某个还没选的选为 \(B_i\)。

  • 应用 \(h_2\) 的堆顶:对应把某个还没选的选为 \(C_i\)。

  • 应用 \(h_3+h_2\) 的堆顶:对应把某个还没选的选为 \(C_i\),然后把一个已经选为 \(B_j\) 的改成 \(C_j\)。

  • 应用 \(h_4+h_1\) 的堆顶:对应把某个还没选的选为 \(B_i\),然后把一个已经选为 \(C_j\) 的改成 \(B_j\)。

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

  • 应用 \(h_1\) 的堆顶:把某个还没选的选为 \(B_i\),会增加 \(h_3\) 的把某个 \(B_j\) 改成 \(C_j\) 的可能性。

  • 应用 \(h_2\) 的堆顶:把某个还没选的选为 \(C_i\),会增加 \(h_4\) 的把某个 \(C_j\) 改成 \(B_j\) 的可能性。

  • 应用 \(h_3+h_2\) 的堆顶:把某个还没选的选为 \(C_i\),然后把一个已经选为 \(B_j\) 的改成 \(C_j\)。这种操作会新增一个 \(B_i\) 和一个 \(C_i\),也就是说 \(h_3,h_4\) 的可能性都会增加。

  • 应用 \(h_4+h_1\) 的堆顶:把某个还没选的选为 \(B_i\),然后把一个已经选为 \(C_j\) 的改成 \(B_j\)。与 \(h_3\) 的类似。

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

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

\(h_3\) 和 \(h_4\) 不需要 pop 的原因是没有任何一种增广路在应用时,会把 \(h_3,h_4\) 作为额外使用的堆顶。

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

标签:选为,增广,没选,题解,Coins,应用,某个,AGC018C,rightarrow
From: https://www.cnblogs.com/FLY-lai/p/18095433

相关文章

  • Atcoder ABC 346 全题解
    闲话上一篇全题解反向不错,如果大家支持我就会继续更。我ABC也打了,ARC也打了,没打好,疯狂掉大分……包括本场比赛也是整整补了EFG三道题,以及ARC死磕D结果使赛后五分钟AC又有素材了……A懒得讲B由于我被B题坑了,所以在此纪念。最简单的方法就是把字符串复制......
  • 20240325每日一题题解
    20240325每日一题题解Problem给出一个整数\(a\)和一个正整数\(n\),求乘方\(a^n\)。输入一行,包含两个整数\(a\)和\(n\)。\(-1000000\lea\le1000000\),\(1\len\le10000\)。输出一个整数,即乘方结果。题目保证最终结果的绝对值不超过\(1000000\)。样例输入23样......
  • 动态尺寸加载libpag文件白边问题解决方案
    加载pag文件时,最理想的情况是canvas的宽高和pag资源文件的宽高一致,或比例一致。否则就会出现四周白边(页面底色),除非是按平铺的样式进行设置(源码暂未找到对应方法)。而对于页面宽高不定的情况下,就无法保证pag文件能适配页面,如果pag文件底色和父级页面底色不一致,就会表现出来......
  • CSP-S 2023 题解
    T1听说有歧义?希卓没看懂。不过真的水。你看能把它拧成什么正确密码。#include<bits/stdc++.h>#defineLLlonglongusingnamespacestd;LLn,sum,a[10][6],p,b[10][6];LLf[100010];intmain(){ scanf("%lld",&n); for(inti=1;i<=n;i++) { for(intj=1;j<=5;j++)......
  • CSP-J 2023 题解
    T1这么水?!赛时AC。思路:小学数学题,我孙子都会做认真点。就是余数和商,小学二年级的知识(毕导:亻尔女子)代码:#include<bits/stdc++.h>#defineLLlonglongusingnamespacestd;LLn,sum;LLt(LLa){ if(a!=1)return1+t(a-((a-1)/3+1)); elsereturn1;}intmain(){......
  • AT_arc175_a [ARC175A] Spoon Taking Problem 题解
    题目翻译link有\(N\)人围坐在一张圆桌旁,按逆时针顺序编号为\(1\)至\(N\)。每个人都有一个惯用手圆桌上有\(N\)把勺子,编号为\(1\)到\(N\),每对相邻的人之间放一把勺子给你一个\((1,\dots,N)\)的排列组合\((P_1,\dots,P_N)\)。在\(i=1,\dots,N\)的顺序中,人......
  • 题解:AT_abc345_c [ABC345C] One Time Swap
    求过审题面翻译给定一个字符串$s$,求执行以下操作一次可以产生的字符串的个数设$N$为$s$的长度。选择一对整数$(i,j)$,使$1≤i<j≤N$,交换$s$的第$i$个和第$j$个字符可以证明,在这个问题的约束条件下,你总是可以得到它思路暴力做法我们可以......
  • JavaScript:void(0) 用法及常见问题解析
    JavaScript:void(0)用法及常见问题解析javascript:void(0);是一种在JavaScript和网页开发中经常使用的技术,尤其在处理链接的行为时。本文将深入探讨javascript:void(0);的用法,以及在使用过程中可能遇到的常见问题和解决方法。什么是javascript:void(0);?javascript:v......
  • LeetCode第390场周赛题解(c++)
    真的无语了,早上怎么都提交不了,显示未知错误。。。结果晚上就可以提交了。唉100245.每个字符最多出现两次的最长子字符串给你一个字符串 s ,请找出满足每个字符最多出现两次的最长子字符串,并返回该子字符串的 最大 长度。示例1:输入: s="bcbbbcba"输出: 4解释:以......
  • [题解]HDU1024 Max Sum Plus Plus
    HDU1024这道题是一道很巧妙的\(dp\)题(虽然优化成一维,可是究其本质算不算二维\(dp\)?如果有明白的麻烦在评论说一下多谢),在上一篇文章——线性\(dp\)模型中也提到过,因为其前身其实就是上一篇写到的「最大连续子段和」。只不过这一题问的不是一段,而是\(m\)段,所以较上一题我们的选择......