反悔贪心&模拟费用流
贪心是一种常用的算法,它能够获得局部最优解,但我们往往需要的是全局最优解,所以我们在贪心的时候加入和反悔的机制,让他能够得到全局最优解。
由于网络流中的退流操作本质上也是反悔贪心,所以在实现反悔贪心时类似费用流的,也会被成为模拟费用流。
一般的实现时在贪心之后加入一个和贪心值相反的值或重构问题使得变成原问题等方式实现。
CF865D Buy Low Sell High
题意:每天可以选择消耗 \(a_i\) 买入一份股票或者获得 \(a_j\) 卖出一份股票(要有股票),或者什么都不做,最大化收益。
这个问题也叫老鼠进洞问题。
我们考虑到达第 \(i\) 天的时候,我们找到前面几天中最小的买入价格 \(a_j\) ,它会对答案做出 \(a_i-a_j\) 的贡献。
但由于一天只能买入一张或者卖出一张,在类似 1 2 100
的结构中贪心就时错误的。
不难发现,如果 \(i\) 会选定 \(j\) 和它做贡献,则在全局最优解中, \(a_j\) 也一定会做贡献。
令 \(a_j\) 与 \(a_k\) 做出 \(a_k-a_j\) 的贡献( \(j<i<k\) ) 。由于 \(a_k-a_j=a_k-a_i+a_i-a_j\) 。
右式的后两项就是我们贪心的结果,这也就意味着,如果我们再在后面贪心的取一次 \(a_k-a_i\) 即可。
题目有每个数只能买入或卖出一次的限制,所以我们只要在贪心取数的时候额外加入一个 \(a_i\) 即可。
使用小根堆维护最优解,最终复杂度为 \(O(n\log n)\) 。
Luogu P1484 种树
题意:给定一个长为 \(n\) 的序列,从中选 \(k\) 个数不能选相邻的数,最大化加和。
因为不能选择相邻的数,所以在取了最大值 \(a_i\) 的时候, \(a_{i+1}\) 和 \(a_{i-1}\) 就不能选了,但可能全局最优解应该是 \(a_{i+1}+a_{i-1}\) 的。
例如在 \(n=5,k=2\) 时,数据 1 99 100 99 1
可以卡掉纯贪心。
考虑 \(a_{i+1}+a_{i-1}=a_{i}+(a_{i+1}+a_{i-1}-a_{i})\) ,比我们的贪心值多了一个 \(a_{i+1}+a_{i-1}-a_{i}\) 。
但它同时也去多取了一个数,所以考虑 \(a_{i-1},a_i,a_{i+1}\) 三个数在取了 \(a_i\) 后替换成 \(a_{i+1}+a_{i-1}-a_{i}\) 这一个数。
发现这样不影响限制,维护双线链表和大根堆即可。
集训队互测 Round1 Astral Birth
题意:给定一个长为 \(n\) 的 \(01\) 串,询问 \(i=1,2\dots n\) ,将原串分为 \(i\) 的子串后按任意顺序拼接,最长不降子序列的长度的最大值。
不难证明最优答案必然把答案划分成若干个连续的 \(00\dots0\) 或 \(11\dots1\) 。
在分割段数减少的时候,我们需要删去一些连续段来使得损失最小。
我们会发现三个性质:
- 删去边上的串可以减少一次分割,删去中间的串可以减少一次分割。
- 删去相邻的两端一定不优。
- 可以保留一个形如 \(0\dots 01\dots 1\) 的结构。
所以我们需要求的就是看有多少个不相邻的连续段在最终答案中不做贡献,先枚举两端的段取不取,在考虑中间的。
这就变成了类似上一题的做法,负责都为 \(O(n\log n)\) 。
在段数小于 \(3\) 的时候不一定有 \(0\dots 01\dots 1\) 结构,所以需要特判,可以在 \(O(n)\) 的复杂度完成。
CF730I Olympiad in Programming and Sports
题意:每个人有一个数值 \(a_i\) 与 \(b_i\) ,选取 \(p\) 个 \(a_i\) 和 \(s\) 个 \(b_i\) ,两两不等,最大化加和。
用费用流的思想考虑这道题,会发现每个人会有四种状态:
- 没有被选,准备去编程
- 没有被选,准备去运动
- 被选去编程,但想去运动
- 被选去运动,但想去编程
对于每一种选择,维护一个大根堆,在选择状态 3 或 4 时,需要在 1 或 2 中找一个补齐空缺保证复杂度。
每一次操作后 \(p\) 和 \(s\) 中有一个减少了 \(1\) ,所以最终复杂度为 \(O(n\log n)\) 。
CF280D k-Maximum Subsequence Sum
题意:维护一个序列,支持单点修改和区间内至多k段不相交子段和。
比较经典的 GSS 问题,每次找到区间最大的子段,其对答案做出贡献,然后将区间内的所有值取反。
用线段树维护区间和\最大前缀\最大后缀\最大子区间,复杂度为 \(O(n\log n+m\log n)\) 。
[NEERC2016]Mole Tunnels
题意:给定一个大小为 \(n\) 的树, \(1\) 为根, \(i\) 节点的父亲为 \(\left\lfloor\dfrac{i}{2}\right\rfloor\) 节点,每个点都有 \(c_i\) 的容量,有 \(m\) 次询问,每次额外加入一个鼹鼠,问所有的鼹鼠需要走过总计多少次边才能使每个节点的鼹鼠数量都小于容量。
考虑只有一种鼹鼠时,贪心策略是让鼹鼠走到距离最近的还有值的点,但这时就会出现问题,加入我们取出其中的一条链来看。
现在在最中间有一个鼹鼠,用贪心的策略,我们假设它选择了往右走两步(如果往左反转之后等效),答案为 \(2\) 。
这是又来了一只鼹鼠,刚好在最右边的点,则用贪心的策略它会走向最左边的节点,答案为 \(2+4=6\) 。
但是我们发现,答案应该而 \(2\) ,而多出来的 \(4\) 就是在于红蓝箭头都走了的两条边。
假如一条边的两端都有一只鼹鼠,交换他们为位置与不交换是等效的,但是浪费了 \(2\) 的步数。
所以我们考虑加入类似网络流中的增广机制,如果一条边 \((u,v)\) 在 \(u\rightarrow v\) 的时候做了 \(1\) 的贡献,则在下次 \(v\rightarrow u\) 的时候,它做 \(-1\) 的贡献抵消掉原来的贡献。
所以我们用一个数组存储每条边目前累计走过的次数和方向即可。
由于树结构为完全二叉树,所以复杂度是 \(O(n\log n)\) 。
[NOI2019] 序列
题意:给定两个序列 \(\{a_n\}\) 与 \(\{b_n\}\) ,分别从两个序列中选出 \(K\) 个元素,要求至少有 \(L\) 个下标 \(a_i\) 和 \(b_i\) 同时被选,最大换选出的元素和。
这样的限制条件很想费用流的模型。
首先考虑转化条件,不好处理至少有 \(L\) 对相同下标,更改为至多有 \(K-L\) 对不相同的。
费用流模型有5种情况:
- 选取一组下标相同的数。
- 选取一组下标不同的数,消耗 \(1\) 的不同流量(这个是所有决策中局部最优的)。
- 选取一组 \(a_i\) 与 \(b_j\) ,且 \(b_i\) 与 \(a_j\) 已经被选,回复 \(1\) 的不同流量。
- 选取一组 \(a_i\) 与 \(b_j\) ,且 \(b_i\) 已经被选。
- 选取一组 \(a_i\) 与 \(b_j\) ,且 \(b_i\) 已经被选。
由于不同决策的优先度不同,在满足要求的情况下贪心顺序应为: \(1\rightarrow 3\rightarrow (4,5)\rightarrow 2\) 。
CF335F Buy One, Get One Free
题意:给定一个长为 \(n\) 的序列,你可以一次取出至多两个不相等的数,代价是两个数中的较大值(一个付钱,一个白嫖),最小化代价和。
考虑费用流模型:我们先贪心地从大到小选择和白嫖,如果到后面有更优的决策时,我们会放弃白嫖之前的某一个,而换成给他付钱,然后白嫖另外两个。
由于价格相同的不能同时取,所以考虑将所有价格相同的一起处理。
设白嫖的馅饼价格为 \(k\),(可能是虚空馅饼)。
如果 \(k<a\),我们付出 \(k\) 的代价,并白嫖两个 \(a\) 价格馅饼,如果只有一个,我们便空出了一个白嫖的位置。
如果 \(k\geqslant a\),我们如果不白嫖,我们会有 \(2a\) 的代价,同时获得两个空位;如果我们不白嫖,我们将会有 \(k\) 的代价,同时没有空位。
发现,上面一种情况相当于是有一个代价为 \(2a-k\) 的虚空馅饼抵消了我们选择 \(k\) 的操作。所以此时我们的方案就是,如果 \(2a-k\geqslant 0\) ,我们便消耗 \(k\) 的代价,白嫖了 \(2a-k\) 与 \(k\) 两个馅饼,由于 \(2a-k\leqslant k\) 所以一定会优先消耗馅饼 \(2a-k\) ,不会出现问题。
AT AGC018C Coins
题意:给定 \(n\) 个三元组 \((a_i,b_i,c_i)\),你需要选择 \(x\) 个 \(a\),\(y\) 个 \(b\),\(z\) 个 \(c\)(满足 \(x+y+z=n\)),每个三元组中只能选一个,最大化选择的数的和。
考虑每个数先直接选择 \(a_i\) ,然后将 \(b_i,c_i\) 改成 \(b_i-a_i,c_i-a_i\),题意变为在 \(n\) 个数中选择 \(y\) 个 \(b\),\(z\) 个 \(c\),一个下标只能选一次,最大化加和。
考虑费用流模型:
- 在 \(y\neq 0\) 时,选择 \(b_i\),\(y\gets y-1\)。
- 在 \(z\neq 0\) 时,选择 \(c_i\),\(z\gets z-1\)。
- 在 \(y\neq 0\) 时,选择 \(c_i\),同时将已选择的 \(c_j\) 改为 \(b_j\),\(y\gets y-1\)。
- 在 \(z\neq 0\) 时,选择 \(b_i\),同时将已选择的 \(b_j\) 改为 \(c_j\),\(z\gets z-1\)。
使用四个堆维护即可,复杂度 \(O(n\log n)\)。
反悔贪心&模拟费用流的更多相关文章
- UOJ #455 [UER #8]雪灾与外卖 (贪心、模拟费用流)
题目链接 http://uoj.ac/contest/47/problem/455 题解 模拟费用流,一个非常神奇的东西. 本题即为WC2019 laofu的讲课中的Problem 8,经典的老鼠进洞 ...
- BZOJ4977[Lydsy1708月赛]跳伞求生——贪心+堆+模拟费用流
题目链接: 跳伞求生 可以将题目转化成数轴上有$n$个人和$m$个房子,坐标分别为$a_{i}$和$b_{i}$,每个人可以进一个他左边的房子,每个房子只能进一个人.每个房子有一个收益$c_{i}$, ...
- luogu P5470 [NOI2019]序列 dp 贪心 费用流 模拟费用流
LINK:序列 考虑前20分 容易想到爆搜. 考虑dp 容易设\(f_{i,j,k,l}\)表示前i个位置 选了j对 且此时A选择了k个 B选择了l个的最大值.期望得分28. code //#incl ...
- 贪心(模拟费用流):NOIP2011 观光公交
[问题描述] 风景迷人的小城Y 市,拥有n 个美丽的景点.由于慕名而来的游客越来越多,Y 市特意安排了一辆观光公交车,为游客提供更便捷的交通服务.观光公交车在第0 分钟出现在1号景点,随后依次前往2. ...
- 模拟费用流 & 可撤销贪心
1. CF730I Olympiad in Programming and Sports 大意: $n$个人, 第$i$个人编程能力$a_i$, 运动能力$b_i$, 要选出$p$个组成编程队, $s ...
- [UOJ455][UER #8]雪灾与外卖——堆+模拟费用流
题目链接: [UOJ455]雪灾与外卖 题目描述:有$n$个送餐员(坐标为$x_{i}$)及$m$个餐厅(坐标为$y_{i}$,权值为$w_{i}$),每个送餐员需要前往一个餐厅,每个餐厅只能容纳$c ...
- 【BZOJ3502/2288】PA2012 Tanie linie/【POJ Challenge】生日礼物 堆+链表(模拟费用流)
[BZOJ3502]PA2012 Tanie linie Description n个数字,求不相交的总和最大的最多k个连续子序列. 1<= k<= N<= 1000000. Sam ...
- 【bzoj1150】[CTSC2007]数据备份Backup 模拟费用流+链表+堆
题目描述 你在一家 IT 公司为大型写字楼或办公楼(offices)的计算机数据做备份.然而数据备份的工作是枯燥乏味的,因此你想设计一个系统让不同的办公楼彼此之间互相备份,而你则坐在家中尽享计算机游戏 ...
- 【CF280D】 k-Maximum Subsequence Sum ,线段树模拟费用流
昨天考试被教育了一波.为了学习一下\(T3\)的科技,我就找到了这个远古时期的\(cf\)题(虽然最后\(T3\)还是不会写吧\(QAQ\)) 顾名思义,这个题目其实可以建成一个费用流的模型.我们用流 ...
- Codeforces 280D k-Maximum Subsequence Sum [模拟费用流,线段树]
洛谷 Codeforces bzoj1,bzoj2 这可真是一道n倍经验题呢-- 思路 我首先想到了DP,然后矩阵,然后线段树,然后T飞-- 搜了题解之后发现是模拟费用流. 直接维护选k个子段时的最优 ...
随机推荐
- socket TCP DPT 网络编程
复习: ARP协议: 广播和单播 通过ip地址获得mac地址 机器A发起一个arp请求(只包含A的ip地址) 交换机接收到请求,广播这条消息 所有的机器都会接受到这条请求,只有需要寻找的机器B的ip地 ...
- docker 安装 ElasticSearch 和 Kibana 及ik 中文分词器
本文为博主原创,未经允许不得转载: 1. 使用 docker 下载 elasticsearch 7.6.1 docker pull elasticsearch:7.6.1 2. 启动 elastic ...
- Linux 安装 mysql 及配置存储位置
本文为博主原创,未经允许不得转载: 新申请的服务器,需要确认服务器的磁盘是否进行了挂载,可参考这篇文章:https://www.cnblogs.com/zjdxr-up/p/14873242.html ...
- 程序&命名-执行环境
开发程序执行环境 系统级别 -- 编译器或解释器 程序级别 -- 命令行参数.配置文件 执行级别 -- 进程.线程.协程运行时上下文(树(命名空间 -- 函数-局部变量.包或模块-全局变量)) 命令行 ...
- [转帖]SPEC CPU 2017 单线程整数性能测试与总结 (2022)
https://zhuanlan.zhihu.com/p/574105237 x86处理器的整数性能在过去4年间取得了长足的进步 x86处理器移动端性能缩水非常严重 ARM公版的旗舰级处理器相比前代进 ...
- [转帖]Nginx反向代理中使用proxy_redirect重定向url
https://www.cnblogs.com/kevingrace/p/8073646.html 在使用Nginx做反向代理功能时,有时会出现重定向的url不是我们想要的url,这时候就可以使用pr ...
- [转帖]iptables的四表五链与NAT工作原理
本文主要介绍了iptables的基本工作原理和四表五链等基本概念以及NAT的工作原理. 1.iptables简介 我们先来看一下netfilter官网对iptables的描述: iptables is ...
- [转帖]009 Linux 文件大小统计与排序 (du 于 df 和 sort)
https://my.oschina.net/u/3113381/blog/5463932 01 du 与 df 作用与区别? Linux 最有用最常用的统计文件大小命令是什么?无疑就是 du 和 d ...
- HTTPD 搭建正向代理 使无网络访问权限的服务器能够访问互联网服务的快捷办法
背景 公司有保密要求比较高,数据安全要求比较高的企业客户,要求核心业务服务器部允许直接访问互联网,但是因为我们有一些OCR识别以及发票查验等的场景需要连接云端的服务才可以正常使用, 所以这里面就存在安 ...
- vscode搜索框不见了如何显示