[关闭]
@Holmesee 2020-06-12T22:46:12.000000Z 字数 883 阅读 945

反悔贪心

未分类


有人把这个东西分成两种:贪心自动机和贪心堆。在此主要介绍前者。

例子

树上k条路径最大权值和

边有边权,树上选择k个边不相交的路径,总和最大(权值有正有负)

求k次树的直径,每次把直径上的边权取反即可。

CF865D Buy Low Sell High

已知接下来 天的股票价格,每天可以买入当天的股票,卖出已有的股票,或者什么都不做,求 天之后最大的利润。

显然答案是由若干对卖出价-买入价组成的。维护一个小根堆。对于 ,先放进堆里作可能的买入价,如果 大,则 ,但是 作为卖出价可能不是最优的,所以我们把放一个 进堆,这样即使以后可能有比 更大的卖出价也能反悔。

BZOJ2151 种树

个位置,每个位置有一个价值。有 个树苗,将这些树苗种在这些位置上,相邻位置不能都种。求可以得到的最大值或无解信息。

维护一个大根堆,每次选最大元素 ,把它删了后放个 ( 的相邻元素)进堆就行了。

楼房搭建

有一个非负序列 ,每次可以进行两种操作:
1.
2.
求使得所有元素小于等于 的最小操作次数。


我们朴素的贪心策略当然是对 尽可能多地使用 操作,考虑反悔 操作,就是上图中的第一个反悔,相当于添加了一个新的操作叫 操作,可以使 ,但是 操作也需要反悔,于是有了另外的两种反悔。
Code

  1. for(int i = 0; i < n; i++)
  2. {
  3. h[i] = max(h[i], 0ll);
  4. t1 = min(h[i] / 3, a[i]);
  5. h[i] -= t1 * 3;
  6. t2 = h[i] / 2;
  7. h[i] -= t2 * 2;
  8. t3 = h[i];
  9. h[i] -= t3;
  10. h[i+1] -= t2 + t3 * 2;
  11. a[i+1] = t1 * 2 + t2;
  12. ans += t1 + t2 + t3;
  13. }

共性

  1. 问题是一个线性的决策过程,每次决策要付出一个代价,总代价是一定的。
  2. 每次采取朴素贪心策略(即局部最优),但是要把撤销操作加入可选决策集。
  3. 撤销操作应该满足:能够完全填补被撤销操作,且代价要比被撤销操作大(当然,往往恰好大 )。
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注