题解 NOI2019 序列

最近打了场CF,发现那个E2很眼熟,经过yg的提醒意识到和这题有点类似,所以就来写这题了……

有个看一眼就能想到的假做法是这样的:先选\(L\)\(a+b\)最大的,再选\(K-L\)\(a\)最大的和\(K-L\)\(b\)最大的。

这时候你会发现这样一组数据:

3 2 1
50 50
0 52
200 0

这样选我们会选\(\{200,0\},50,52\),实际上我们应该选\(\{50,50\},52,200\)

发现主要矛盾在于大带小,而这个小的应该舍弃。

那我们考虑先钦定一些,再用更优的替换。

假如我们按照上面那种贪心先钦定好了选择的树,然后我们从第\(L+1\)组开始往后找每一组进行替换。

1.这组\(a_i,b_i\)都没有被选过

如果现在成对的数量恰好是\(L\)

如果我们两个都选,可以拆一组\(+\)替换一个零散的,或者替换两个零散的;如果我们两个只选一个,那只能替换一个零散的。

如果现在成对的数量\(\gt L\)

首先恰好是\(L\)时的替换方法肯定是可行的,然后两个都选还可以拆两组,只选一个还可以拆一组,但是要实时更新成对的数量。

这个直接拿堆或者\(multiset\)维护就能找到最小的,然后插进去替换。

2.这组\(a_i,b_i\)有一个被选过

假设选了\(a_i\),则把\(b_i\)和当前选过的最小的\(b_i\)进行比较,如果比它大就把它换下来。因为不管前面是拆了一组还是换了零散的,成对的数量肯定不会减少,所以这样做肯定是对的。如果选了\(b_i\)就同理换\(a_i\)。然后实时更新现在成对的数量。找最小和上一种情况一样。

posted @ 2020-07-01 09:39  kylin_xy  阅读(221)  评论(0编辑  收藏  举报