【笔记】反悔贪心
若干见到的题和思想
假设最优的结果的形式,然后“反悔”
感觉就是以这种方式添加条件(由于已经是答案,我们再做修改的话已经没有“后效性”,因为修改后可以直接当成答案,从而可以比较优劣),然后倒推出实际上最优的结果形式
另外应当指出,我们的目的是要得到答案的一种可能形式,即,若取到答案的极值,则必存在答案的一种安排方式符合我们设定的形式,我们不保证不同形式一定取不到答案;之所以这么做,是为了先得到一种遍历顺序,且保证答案的一种包含在其中。
例题 [USACO12FEB]Cow Coupons G
我们先以 C 排序,然后假设最优答案形式就是其中随意的若干项。接着考察有无更优策略时我们发现,对于一个用了券的物品,如果其前面存在一个买都没买的物品,那么显然不买当前物品而用这个券去买前面那个,这个新的答案会更优(物品个数不变,还多了一些钱);于是就“反悔”去买了前面未买物品中 c 最小的那个
那么经过有限次这种“反悔”,答案的形式就变成了:前面连续一段都被买,且 K 张券都用在这里了,然后后面断断续续地不用券买了一些。
于是我们推出了答案的(一种可能可做的)形式。在此题中,我们只需要扫一遍得到购买每个长度的前缀连续段对应的最小花费(用堆做),以及对应的剩余钱在后半段最多能买多少物品(由于此时都不用券,我们只需要再用一个堆维护,随着预算的缩减和指针的后移不断弹出已经不属于当前区间的和若干最贵的物品,直到在预算内就行了(有一个小证明:由于贵而被弹出了的物品,不可能因为之后有一个因为不在区间而被弹出的物品而重新回到堆中);另外,此题对于此处又用一个数组维护了“是否在堆内”的信息,并用一个单独的变量记录堆此时的大小,这用来解决需要弹出堆内指定元素的问题)
例题 luoguP2300 合并神犇
即令合并后段数最多。猜想:必存在一种取到最多段数的方式,且其最后一段的值正是所有方案中最小的。即,等效成问题:令合并后,最后一段的值最小。
贪心的证明:假设再反悔:假设存在一个答案,段数更多,但最后一段的值却不是所能取到中最小的,那么考虑对这个答案做修改,使之最后一段取到最小且不使段数变少。倒过来依次对比两个答案的段:
| | | | | |
| | | | |
必存从倒数某处开始,第一行的划分点在第二行对应划分点的后面(该例是倒数第 4 个 | ),于是把第一行变成:
| | | | | |
显然合法,证毕
于是 dp 。另外题解似乎入手方向不同一样,先放着(
反悔堆
原来已经是一个题型了(
见到的形式是取或不取的决策(有点像多维背包?):我们可以先通过假设形式得到一种可行的遍历顺序(如果待选物品没有给出特定顺序的话),然后按照这个顺序,维护一个“当前已取物品”的堆(比如价值是物品个数):我们一般需要保证每次决策后答案至少不会变差,然后要么往堆里扔东西,要么用当前的新东西换出堆里最差的那个。
例题 [USACO12FEB]Cow Coupons G 见上
例题 [JSOI2007]建筑抢修
我们先考虑以什么顺序遍历(强调,确定一个合理的顺序的唯一要求,就是答案的一种满足这个顺序)
不妨考虑以 T2 排序,因为假设有一种答案,其 T2 并非升序,我们不妨取里面 T2 最大的那个,把它放到最后面,显然答案仍然合法,如此操作,即可使 T2 有序。那么显然,这种遍历顺序可以得到我们想要的答案。
于是依次考虑当前物品能不能放,不能放的话考虑能不能换出里头的一个物品让这个背包更轻一些,如此做下去。
例题 luoguP2107 小Z的AK计划
已有遍历顺序,但是遍历时容量会变小,所以考虑把当前物品放进去后,往外弹物品直到再次放得下。当然,这里的答案是途中的最大物品数。
其实不是很清楚“先弹到满足容量限制,再考虑当前物品的去留”这个写法的问题,总之先记在这(假装会看

贪心 orz
浙公网安备 33010602011771号