csp-s2025第一题题解

题目传送门:洛谷P14361社团招新(club) 

比赛的过程中太过于浮躁粗心大意导致我第一题没做出来,赛后研究了一下,欣赏了几篇dalao的文章,来保存分享一下贪心思路


首先,根据题意不难得知,我们需要一种算法来实现有限制的最大值,而能实现这种思路的算法除了贪心就是动态规划 (还有暴力) 再根据数据范围来判断,10e5→线性→贪心!!!(还可能是线性DP,但为什么不选择原因后面讲)

再想贪心的思路,先抛开限制,光求最大值的话就很容易了,遍历每个人,选出当前人满意度的最大值,加到答案中,就可以AC了。OK!收工,下班

 
 
 
 
 
 
 
 
 
 
 
 
 
 

了吗?

并没有,我们还有一个硕大的限制摆在那里呢↓↓↓


硕大的限制


那么这个限制该如何破解呢?

当↑当↑当↑当↓ !!

反悔式贪心来也!

反悔式贪心,顾名思义,就是在贪心的过程中发现有更小的代价可以替换之前更大的代价,那么就进行反悔。

应用

1.使用优先队列(priority_queue)建小跟堆储存当前人的最大值与次大值的差。
2.容易证得,当有一个社团的人数超过n/2时,其他两个社团一定没有超过,所以这是只需找出大于n/2的那个社团,再将答案减去其最大值与次大值的差的最小值(堆顶值),并不断删去这个社团的人(也就是弹出堆顶)直到数量小于等于n/2,最终的答案就是正确答案。

重中之重→贪心证明

前提:出现了超过n/2的情况
每个人的贡献有两种情况:

  1.三个社团满意度的最大值
  2.当迫不得已要更换社团时,剩下的两个社团满意度中的最大值

可能有人会问,为什么没考虑换了一次还要再换一次社团的情况?不会的,因为在前面的证明之中,
我们知道,最多有一个社团超出n/2个人,所以每个人最多只需要换一次社团就可以达到最终目的。
所以说,为了实现更换的操作,我们可以在加入社团的过程中,同时存储最大值与次大值的差,在最
后将减去超出n/2的部分的最大值与次大值的差,就可以实现更换队伍,这样也可以理解,为什么要
用优先队列小根堆来存了————减去的值越小,剩下的值越大。

综上,得证。

OK!下班!

 
在这里求个小关注吧(●'◡'●)

posted @ 2025-11-10 22:00  Guojunning  阅读(10)  评论(0)    收藏  举报