这题真是一环扣一环,做了好久好久,好题啊!
首先通过题意我们可以敏锐的捕捉到:虽然可以跨楼相连,但是这样是没有意义的,因为相邻的两个点相连一定比跨楼相连更优。
我们将楼与楼之间的距离求出来(n-1个数)那么问题就转化为:在n-1个数中选k个数使得他们相加起来最小,且选了一个数后相邻的两个数不可以再选。
那也就是说,我们需要开一个小根堆维护最小值minn,如果选择了当前的最小值minn,那么最小值两边的值都不可以选,那么如果选了两边的反而更优呢??这里就把我难住了,其实啊,这题最精妙的部分就在于此。我们可以回想一下网络流“反向边退流”的思路,当我们发现这样子不优的时候可以通过反向边流回去,那么这题也与之同类,我们也可以设置一个“反向边”来反悔。
那么如何设置反向边呢?我们往堆里加进一个新点q,设minn左边的点权值为prev,右边的点权值为next,那么q的权值就为prev+next-minn,为什么?如果我们在往后的决策中选到q这个元素,然后把它加进ans里面,那么我们之前加的minn的影响也随之删除了(minn+prev+next-minn=prev+next),取而代之的是minn两边的prev和next,成功完成了反悔的过程。
具体过程:
取出最小值1,ans+=1
将他两边的2、
[BZOJ1150][CTSC2007]数据备份Backup(贪心+堆+链表)
最新推荐文章于 2021-08-15 21:46:26 发布