Hoping for the best but |

EricQian06

园龄:4年6个月粉丝:24关注:43

2021-11-17 18:27阅读: 123评论: 1推荐: 2

学习笔记—反悔贪心

djy 的《浅谈反悔贪心》,这里做的题都来自反悔贪心题单

update on 2022.7.29:以前写的太乱了,重构了文章。

反悔贪心

反悔贪心类似 DP,每天我们都可以进行一定操作使得当天我们的收益达到最大值,但是这样的操作可能会使得后面几天达不到最优,这就迫使我们放弃前面的决策。

我们将放弃前面的决策称为反悔,做出新的决策称为贪心,我们需要做的就是在所有决策中选择最优的那个。

例题

CF865D Buy Low Sell High

已知接下来 n 天的股票价格,每天你可以买进一股股票,卖出一股股票,或者什么也不做。n 天之后你拥有的股票应为 0,当然,希望这 n 天内能够赚足够多的钱。

考虑一次股票交易的过程,一天内买入一次再卖出一次等同于什么也没发生,于是我们考虑一个贪心,每次让之前最小的那个和当前这个配对。

但是这样是错误的,可能将一个较小的日子留给后面的更优,所以我们需要反悔的操作,让后面的将这一天的决策抵消掉。

设第 i 天的交易价格为 ci,则在 i,k 之间的 一次交易收益就是 ckci

如果我们已经在 j 时将 ij 匹配了,我们已经得到了 cjci 的贡献,现在我们需要将另外的贡献补上:ckci=(ckcj)+(cjci)

这样我们只用在这一天交易结束后将这天的卖出价格加入堆中即可。

P2107 小Z的AK计划 & P4053 [JSOI2007]建筑抢修

在一条数轴上有 n 个点,初始在 0 位置。每向正方向走一步都消耗 1 单位的时间,每到达一个点可以花费 ti 的时间 获得 1 的收益,也可以直接路过。

m 的时间内,最大收益是多少?

n105,0m,xi1018,0ti109

从前往后枚举我们走到哪里,将新的点加入决策。

什么时候需要反悔?当已经消耗了 >m 的时间。选择消耗时间最大的删去即可。

P3620 [APIO/CTSC 2007] 数据备份

一个环(链)上有 n 个元素,要求选取的任意两个元素互不相邻,求选出 k,k[1,n+12] 个元素分别可以获得的最大价值是多少。

每次都要新选择一个点,我们有两种操作:

  • 加入一个独立的点。
  • 将与一些点相邻的点同时取反。

只用一个链表,加入一个点后将 p+sv 替换为这个点的权值即可,用堆每次选择最大值即可。

CF730I Olympiad in Programming and Sports

n(n105) 个人,第 i 个人有属性 ai,bi,要求选出 A 集合至多 p 人,B 集合至多 s 人,使得选出的人相应属性值之和最大。

先选出 ai 最大的 p 个加入 A 集合,之后一个一个加上 B 集合,我们每次有以下两种操作:

  • 直接加入一个 B
  • 将一个人由 A 转为 B,再选择一个 A

用三个堆对上面信息分别维护即可!

update:网络流做法:

  • 源点 s 到每个点建一条流量为 1,费用为 0 的边(每个人只能只能参加一种比赛)。
  • 建三个汇点,汇点 t1 控制参加编程的,汇点 t2 控制参加体育的,汇点 t 控制参加 t1t2 的总人数。
  • 每个人两种实力分别向 t1t2 建流量为 1,费用为负实力。

然后就跑最小费用最大流啦!

AT2672 [AGC018C] Coins

n(n105) 个人,第 i 个人有属性 ai,bi,ci,要求选出 A,B,C 集合分别 p,q,s 个人,保证 p+q+s=n,使得选出的人相应属性值之和最大。

一种比较显然的想法是将将 Bi 赋为 BiAiCi 赋为 CiAi,就转化为了上一个问题。

update:有一种可以推广到 4,5, 中限制的做法:

发现每次操作我们只有以下几种方案:

  • xy,yz,zx
  • zy,yx,xz
  • xy,yx
  • xz,zx
  • yz,zy

用六个堆维护即可。

CF802O April Fools' Problem medium & hard

每天可以花费 ai 准备一题,花费 bi 打印一题,每天最多准备一题打印一题,求打印 k 题的最小花费。

如果没有 k 的限制,那可以将准备看作买入一只股票,打印看作反向卖出一只股票,转化为第一题的套路。

考虑如何限制 k 只股票。如果我们将每次买卖的收益同时增加一个 d,买卖的优劣性相对不变,但我们会在原来的基础上多进行一些交易。那么我们二分这个 d 直到正好购买 k 次股票即可。

CF436E Cardboard Box

n 个关卡,对每个关卡,你可以花 ai 代价得到一颗星,也可以花 bi 代价得到两颗星,也可以不玩。问获得 w 颗星最少需要多少时间。

我们进行 w 次操作,使我们多选择一棵星星,有以下几种方法:

  • 直接选择一颗星星;
  • 将一颗星星变为两颗;
  • 将一颗星星由一颗反悔为不选择,再选择两颗;
  • 将两颗星星反悔为一颗,再选择两颗。

那么我们需要维护 ai(min&max),bi(min),biai(min&max) 五个堆。

P5470 [NOI2019] 序列

给定长度为 n 的数组 {a},{b},要求在他们中分别取恰好 k 个值,且相同下标且 a,b 中都选取的对数 l,求最大选择价值之和。

n2×105

先在两个数组中选择最大的 k 个,如果相同位置的不到 l,考虑依次增加。想要增加一个相同位置,有以下四种方案:

  • 将一个单独选择的 a 变成一个已经选择 b 但没有选择 a 的;
  • 将一个单独选择的 b 变成一个已经选择 a 但没有选择 b 的;
  • 将一个单独选择的 a 和一个单独选择的 b 都删去,变成一个没有选择的 ab 对;
  • 将一个已经选择的 ab 拆掉,和一个单独选择的 a、单独选择的 b 分别合并变成两个 ab 对。

6 个堆分别维护上面的选择情况,取最大值转移即可。

(乱入)贪心杂题

P2512 [HAOI2008]糖果传递

n 个小朋友坐成一圈,每人有 ai 个糖果。每人只能给左右两人传递糖果。每人每次传递一个糖果代价为 1。问最后所有人糖果数量均衡后的最小代价。

n106

如果题目只是在链上,就变成了均分纸牌的问题,假设每个人现有纸牌数为 ai,平均为 aveaiave 前缀和为 prei,则答案为 |prei|

回到这道题上,发现最优解一定存在环上两个人之间不存在糖果传递,可以想到断环成链。

如果断掉环上第 k 条边,则贡献依次为 |pre1prek|,|pre2prek|

这就是“仓库选址”问题啦!直接将 k 定位所有 pre 的中位数,求出答案即可。

P8272 [USACO22OPEN] Apple Catching G

假设在 a(ax,at) 点有奶牛,在 b(bx,bt) 有苹果 (atbt)a 可以借助 b 的充要条件为:

ax(btat)bxax+(btat){ax+atbx+btaxatbxbt

第二个式子直接 xt 从小到大的顺序搞定(注意如果值相同 t 大的优先),这样只要每个数匹配在它之前的点就都是合法的,接下来只用满足第一个式子。

考虑两头奶牛 a1,a2(axat<bxbt) 一起匹配苹果,我们会让 a1 优先匹配苹果中 bx+bt 最小的,把剩下的留给 a2

为什么这样是对的呢?

显然 bx+bt 越小越难被匹配,那么如果可以被匹配,直接匹配一定最优。

而且如果 a1a2 都能够匹配同一个 b,让他们任何一个去匹配是相同的。

那么就这样被简单地证明了。

实际操作中可以用 multiset 来支持查询比 ax+at 大的数即可。

P2672 [NOIP2015 普及组] 推销员

发现答案只可能是一下两种情况:

  • 选择最大的 x 个推销疲劳值。

  • 选择最大的 x1 个推销疲劳值,并选择一个距离较远的。

至于为什么只选择 x1 个而不是 x2 或更少:

加入我们要将第 x1 大的换为更远的,完全可以用第 x 大的而不是 x1 ,显然这样减小的更少呀。

商店zr

有一个商店,每个天会进货固定 m 中物品分别 bi 个,每个单价为 ai,若 bi=1 表示有无限个。

在接下来的 n 天内,每天顾客会来购买最便宜的 ci 个物品,问最终商店收益为多少。

n,m2×105,1ai,ci106,1bi106,保证存在至少一个 bi=1

考虑这本质是一个贪心过程,每个月丢给你一堆物品,一定先选择小的并有库存的,没了再选择大的。

这样我们的讨论就不能够脱离贪心的特点,固定了向优化贪心的方向走。

Trick单位价值下降的天一定放在一起考虑!!!最后剩下单位价值单调不增的一些连通块,将他们合在一起考虑。

本文作者:EricQian06

本文链接:https://www.cnblogs.com/EricQian/p/15568656.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   EricQian06  阅读(123)  评论(1编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起