反悔自动机与反悔堆——有关贪心的反悔操做

其实两个东西都是堆。区别只不过一个是利用差值等巧妙设计等效权值,另外一个则单纯进行判断。html

 

反悔自动机post

(名字是我本身起的)url

贪心是不能反悔的。由于它就是选择当前的最优解。spa

可是若是当前最优解不是全局最优解怎么办?设计

咱们能够设计一种反悔的方法,而且和贪心的手法结合。htm

使得贪心随便选择,均可以达到正解。blog

姑且叫反悔自动机。get

 

基本的设计思路是:it

每次选择当前直观上最接近最优解的方案。class

可是发现不对。不是最优子结构

而后想办法怎么支持自动反悔。

 

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

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

 

1.经典问题:CF865D Buy Low Sell High

每次用最小的买入,等到一个能够赚钱的天就卖出。

不对是由于:可能这个买入的股票要等到后面更贵的那一天再卖出。

 

利用作差,C-A=B-A+C-B,等效转化

用最小的买最大的,而后把差值计入答案,把B放进去两次,再取B为最小的时候,C-B的差值计入ans,至关于用A买入以C卖出

至关于B没有用,因此额外再加入一次B,以防后面须要用B买入再D卖出。

 

2.相似的:

BZOJ 2151
• 有一个长度为n的环,选择m个两两不相邻的位置。
• 每一个位置都有一个价值Vi,若是选择这个位置就能够获得Vi的价
值。
• 求最大的价值总和,或输出无解。

直观来看,每次选择能选择的最大的价值。

为何不对?由于可能选择了这个最大的,邻居就不能选择。例如1,5,6,5选择了6,就只能再选择1,不如5,5

并且,这个贪心的错误的点就是这里。对于最优解位于其余的位置上的状况,这种贪心都是成立的。

 

考虑怎么支持反悔。

仍是利用差值。

用双向链表维护相邻的关系。用堆维护全部权值的最大值。

选择了A,把W[L[A]+W[R[A]-W[A]建成一个新的点P,令这个P的L,R分别是:L[L[A]],R[R[A]],而后删掉L[A],R[A],

每次取最大值便可。

由于,若是有a,b,c,d,(紧挨着就是相邻),而且a+c>b+d,那么,就有a+c-b>d

因此,即便咱们先选择了b,可是因为a+c-b>d,咱们会接着选择a+c-b,就至关于选择a+c

 

 

 

 

反悔堆:

(名字也是我本身起的)(其实就是一个堆)

这个不是无脑地随便贪心了。由于没有什么等效权值的替换。

其实思路差很少。

咱们仍是按照一个贪心策略贪心,而后找出来不足。

想办法反悔。

和反悔自动机不一样的是,这个要人工反悔。

例题:

[JSOI2007]建筑抢修——贪心反悔堆

相关文章
相关标签/搜索