首页 > 其他分享 >反悔贪心 & 模拟费用流

反悔贪心 & 模拟费用流

时间:2024-08-16 16:40:11浏览次数:13  
标签:老鼠 匹配 leftarrow 反悔 权值 模拟 贪心

反悔贪心 & 模拟费用流

参考资料来源 cyt

前言

很多找到一种可行的方案,匹配(选择)某些东西,使价值最优化的问题可以建出费用流模型。

但是直接跑费用流的复杂度是不对的。

我们又想到可以用简单的贪心思路解决这些问题,然而一般的贪心都假掉了。

于是我们考虑模拟费用流的退流操作来做贪心,这就是反悔贪心,其实也是在模拟费用流的各种操作。


反悔堆

用时一定

用时为 \(1\),使价值最大。

P2949 [USACO09OPEN] Work Scheduling G

按截止时间排序。

接着对于一个工作,若截止时间内还有空,则直接选。

否则我们用一个堆,堆里面放选了的工作,按价值从小到大。

把价值最小的找到,看是否比当前工作的价值更劣,是则用当前工作将它替换。

价值一定

价值为 \(1\),使工作最多。

P4053 [JSOI2007] 建筑抢修

还是按截止时间排序。

还是用堆,把用时最长的找到,看用当前工作替换是否更优。

练习

P2107 小Z的AK计划

显然先按照 \(x_i\) 排序。

相当于枚举一个走到的位置 \(x_i\),然后在这个位置之前的机房选要最多个使 $x_i+\sum k\le m $。

注意到 \(x_i\) 选的机房会继承 \(x_{i-1}\) 的。

则每次先把 \(i\) 选了,让 \(sum\) 加 \(f_i\)。

看 \(sum+x_i\) 是否不超过 \(m\)。

否则,拿个堆,一直把最大的 \(f\) 退掉。

注意是一直退掉,而不是用 \(f_i\) 与堆顶做比较,这是因为堆中存的是走到 \(x_{i-1}\) 这个位置的答案,而不是走到 \(x_i\) 的答案。

若最后 \(sum+x_i\) 不超过 \(m\),则此时选的个数即为走到 \(x_i\) 的最大答案。

对所有可行的答案取最大值即可。

反悔自动机

堆 反悔自动机

CF865D(简易老鼠进洞模型)

考虑在卖出股票时同时结算买和卖。

每一天都买,我们把它插入堆里,插入堆无代价。

每天再看能否卖,若把堆顶现在卖出有收益,则卖出。

但有问题:

我们用当前 \(p_i\) 的价格卖出堆顶的 \(x\) 元买进的股票,收益是 \(p_i-x\)。

但有可能后面有 \(j>i\) 使得 \(p_j-x\) 更优,然而 \(x\) 这个股票已经卖掉了。

解决方案就是,我们用 \(p_i\) 卖掉 \(x\) 的股票时,往堆里再插入一个 \(p_i\),注意这里的 \(p_i\) 和每天买进的股票不同。

这样若后面有 \(p_j\) 更优,则 \(p_j\) 就会匹配上 \(p_i\),此时对答案的贡献和即为

\[(x-p_i)+(p_i-p_j)=x-p_j \]

就变成了用 \(p_j\) 匹配 \(x\),自动变成了最优方案。

双向链表+堆 反悔自动机

P1484 种树

贪心思路:每次选最大的价值,选 \(k\) 次。

然而选了 \(i\) 后 \(i-1\) 和 \(i+1\) 就不能选了,此时可能会出现选 \(i-1\) 和 \(i+1\) 更优的情况。

发现这种情况只能是 \(i-1\) 和 \(i+1\) 同时选,这样才会比 \(i\) 大。

于是考虑选了堆顶 \(a_i\) 后,把 \(i-1,i,i+1\) 这三个点缩成一个价值为 \(a_{i-1}+a_{i+1}-a_i\) 的点,将它插入堆里。

这样下次选到这个点,就相当于选 \(i-1,i+1\),同时把原来选的 \(i\) 退掉,代价和为

\[a_i+(a_{i-1}+a_{i+1}-a_i)=a_{i-1}+a_{i+1} \]

拿一个双向链表维护当前的前驱和后继即可。

老鼠进洞模型

UOJ 455 雪灾与外卖

有 \(n\) 个老鼠,\(m\) 个洞,老鼠有坐标 \(x_i\),洞有坐标 \(y_i\),每只老鼠都要进洞。

第 \(i\) 个洞每进一只老鼠花费 \(w_i\) ,最多进 \(c_i\) 只老鼠。

老鼠可以左右移动,花费移动距离的代价。

要求最小化花费。

两个堆 基础模型

考虑洞没有权值,容量 \(c_i\) 都为 \(1\) 时应该怎么做。

先把老鼠和洞放在一起按坐标排序。

为了去掉绝对值的影响,我们把洞匹配老鼠和老鼠匹配洞分开考虑(即让右边匹配左边)。

设 \(i\) 老鼠匹配洞 \(j\),若 \(i<j\),则贡献为 \(y_j+(-x_i)\),反之为 \(x_i+(-y_j)\)。

用反悔贪心的思路,维护一个洞堆和一个老鼠堆,从左往右扫一遍。

如果当前扫到一个老鼠

那么取出洞堆的堆顶让它和这个洞匹配(初始时负无穷处有足够多个洞),设堆顶为 \(v\),对答案的贡献为 \(x_i+v\)。

为了让右边没扫到的洞使这个老鼠能反悔,让它匹配右边一个新的洞。

那么如果它要匹配右边一个新的洞 \(j\),那么代价的增量为 \((y_j-x_i)-(x_i+v)=y_j+(-2x_i-v)\),于是往老鼠堆插入 \(-2x_i-v\)。

如果扫到一个洞

考虑有没有老鼠要反悔来这个洞,从老鼠堆中取出堆顶 \(u\),若 \(y_i+u<0\) 则更优,让老鼠反悔,加上贡献。

若这个洞原本应当让后面一个老鼠 \(j\) 占,于是让这个洞反悔,往洞堆中插入 \(-2y_i-u\)。

贡献和即 \((y_i+u)+(x_j+(-2y_i-u))=x_j-y_i\),是正确的。

若没有老鼠能反悔来这个洞,则直接插入 \(-y_i\)。

就像这样(\(A\) 为老鼠,\(B\) 为洞):

\[B_1\leftarrow A_1\\ \downarrow\\ B_1,A_1\leftarrow B_2\\ \downarrow\\ B_1\leftarrow A_1,B_2\leftarrow A_2 \]

初始时 \(A_1\) 匹配 \(B_1\)。

然后 \(A_1\) 反悔,让 \(B_2\) 匹配 \(A_1\)。

后来 \(A_2\) 才应该匹配 \(B_2\),于是 \(A_1\) 又重新匹配 \(B_1\)。

当然在权值上没有谁匹配谁的关系,我们只需使最后的权值和正确即可。

洞有权值

如果在基础模型的基础上,洞有权值 \(w\) 该怎么做。

区别在于一个老鼠可能会匹配较远的洞。

老鼠匹配洞时有堆最优化,无影响。

而当洞匹配老鼠就有影响了。

首先是贡献为 \(y_i+w_i+u\)。

考虑到我们让洞 \(i\) 匹配老鼠 \(j\) 时,后面可能还有洞 \(k\) 与老鼠 \(j\) 匹配更优。

所以,设 \(u\) 为老鼠 \(j\) 在堆中的权值,则我们用 \(k\) 再匹配 \(j\) 的增量为,\((y_k+w_k+u)-(y_i+w_i+u)=(y_k+w_k)+(-y_i-w_i)\),所以用 \(i\) 匹配完 \(j\) 后,要往老鼠堆中插入 \(-y_i-w_i\),让洞 \(k\) 与这个虚拟老鼠匹配。

由于新增的 \(w\) 的影响,扫到一个洞后,有反悔时插入到洞堆的权值就变成了 \(-2y_i-u+w\),无反悔时插入的权值变为 \(-y_i+w_i\)。

这时你可能会有疑问:

如果洞 \(i\) 在洞堆和老鼠堆插入的两个权值都从堆顶取出了怎么办。

那它应该要长成这样:

\[B_1\leftarrow A_1\\ \downarrow\\ B_1,A_1\leftarrow B_2\\ \downarrow\\ B_1,A_1,B_2,B_3(A_1\leftarrow B_3)\\ \downarrow\\ B_1,A_1,B_2,B_3,A_2(A_1\leftarrow B_3,B_2\leftarrow A_2) \]

其中 \(B_2\) 就是被取出两次的洞,它开始匹配 \(A_1\),后来 \(B_3\) 替换了它,取了一次老鼠堆顶。

然后 \(A_2\) 以为 \(B_2\) 还连着 \(A_1\),取了一次洞堆顶,它以为它替换掉了 \(B_2\) 连着的 \(A_1\),然而 \(B_2\) 实际并没有连着 \(A_1\),那么 \(A_2\) 连 \(B_2\) 时加的权值就不对了。

我们观察一下, 发现这种情况时不可能出现的,因为对于 \(i<j<k<l\),其中 \(i,l\) 为老鼠,\(j,k\) 为洞,\(i\) 连 \(k\) 并且 \(j\) 连 \(l\) 一定不优,因为 \(i\) 连 \(j\) 并且 \(k\) 连 \(l\) 比这更优。

那么对于上面的例子,最后一行会变成 \(B_1,A_1\leftarrow B_2,B_3\leftarrow A_2\) 或 \(B_1,A_1,B_2,B_3,A_2(B_1\leftarrow A_2,A_1\leftarrow B_3)\)。

所以我们不用担心取两次的情况。

有权值,有容量

标签:老鼠,匹配,leftarrow,反悔,权值,模拟,贪心
From: https://www.cnblogs.com/dccy/p/18363154

相关文章

  • 【网络工程师模拟面试题】(1)ARP、MAC与Trunk
    一、二层交换机和三层交换机的区别这道面试题主要考验以下几个方面的知识点:网络基础知识对数据链路层和网络层的理解,包括这两层的功能、作用和相关协议。交换机工作原理深入了解二层交换机和三层交换机分别如何处理数据帧和数据包的转发。网络架构和规划考查面试......
  • Day31 贪心算法part5
    目录任务56.合并区间思路738.单调递增的数字思路968.监控二叉树思路任务56.合并区间以数组intervals表示若干个区间的集合,其中单个区间为intervals[i]=[starti,endi]。请你合并所有重叠的区间,并返回一个不重叠的区间数组,该数组需恰好覆盖输入中的所有区间。思路......
  • 暑假集训csp提高模拟21
    赛时rank47,T120,T20,T330,T445赛时最后想到了T1的正解,可惜没有打出来。整场比赛都在死磕T1的神秘构造,导致本来可以AC的T2没有写,开题的策略不行,太容易死磕了。T1黎明与萤火DestructionofaTree贪心构造。先给一组数据Input:501234Output:YES24135......
  • 『模拟赛』暑假集训CSP提高模拟21
    Rank意外地还凑合,本来以为这场要GG了。A.黎明与萤火原[CF963B]DestructionofaTree签,勉强签了。开始脑子乱,胡乱打了一个含有3个dfs函数,每个函数里含两次遍历链式前向星,不负众望大样例T了。后来也是摸着摸着就出正解了,先一遍dfs跑出基本的数据,然后再一遍df......
  • 【NOIP2016普及组复赛模拟赛】侦察兵
    题目描述mxy沉迷于一个辣鸡游戏不可自拔。游戏地图是一个n*n的矩形,在每个单位格子上有一个数字,代表当前位置的生命体个数,作为一个侦察兵,mxy的任务是计算出她所在位置的左上角和右下角的总人数(不包括她所在的行列)。注意作为一个侦察兵,mxy是不包括在地图上的生命体个数中的......
  • [赛记] 暑假集训CSP提高模拟20 21
    Kanon40pts签到题,但是不会,所以打了暴力;正解时考虑相邻两个雪球,只有两种情况:它们的覆盖区间有交集或无交集,那么如果我们找出了无交集的最后一天,我们就很容易判断剩下的一堆雪该被谁拿走,于是我们二分找出这一天即可;赛时确实想不到二分时间复杂度:$\Theta(n\logn)$;点击查看......
  • 『模拟赛』暑假集训CSP提高模拟21
    『模拟赛』暑假集训CSP提高模拟21终于没RE了!不枉我辛辛苦苦调了几个小时...(但是暴力没打完...(逃T1黎明与萤火DFS序乱糊+贪心注意要先消除叶子结点。Elaina'sCodeintn,fa[N],rdeg[N],hd[N],idx,ans[N],cnt;boolvis[N];stack<int>sta;structEDGE{ intnxt,to;}......
  • 暑假集训CSP提高模拟21
    暑假集训CSP提高模拟21组题人:@Muel_imj\(T1\)P241.黎明与萤火\(10pts\)原题:CF963BDestructionofaTree部分分\(10pts\):生成\(1\simn\)的全排列然后依次判断。\(20pts\):输出NO。正解叶子节点的度数为\(1\),不能直接删除,只能先删除父亲节点后再......
  • 生态系统NPP及碳源、碳汇模拟(土地利用变化、未来气候变化、空间动态模拟)
    由于全球变暖、大气中温室气体浓度逐年增加等问题的出现,“双碳”行动特别是碳中和已经在世界范围形成广泛影响。碳中和可以从碳排放(碳源)和碳固定(碳汇)这两个侧面来理解。陆地生态系统在全球碳循环过程中有着重要作用,准确地评估陆地生态系统碳汇及碳源变化对于研究碳循环过程、预......
  • Day30 贪心算法part4
    目录任务452.用最少数量的箭引爆气球思路435.无重叠区间思路763.划分字母区间思路任务452.用最少数量的箭引爆气球有一些球形气球贴在一堵用XY平面表示的墙面上。墙面上的气球记录在整数数组points,其中points[i]=[xstart,xend]表示水平直径在xstart和xend之间的......