CF513D Social Circles

本文探讨了一个有趣的问题:如何为N个客人安排最少数量的椅子,使得每个客人的左右两侧都有足够的空位。通过分析和证明,文章提出了一种贪心算法,即按左右需求排序并配对,以达到最小化椅子数量的目的。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目

传送门

题目大意

你请了 N ( N ≤ 1 0 5 ) N(N\leq 10^5) N(N105)个客人吃饭,它们的椅子需要围成一个或多个圈,但是客人们都有些害羞,第 i i i个客人希望他的左手边至少有 l i l_i li个空椅子,右手边至少有 r i r_i ri个空椅子,问你最少需要多少个椅子。注意:客人会对自己感到害羞,也就是说,就算他所在的椅子圈只有他一个人,也要满足上述条件。

思路

肯定要让两个客人的左右手匹配得越多越好,也就是说要最小化 max ⁡ { r j , l i } \max\{r_j,l_i\} max{rj,li},如果你足够贪心,直接可以想到:分别按左右手排序,最大的左手和最大的右手匹配,以此类推,然后你就AC了。

排完序后,假如不是 r 1 r_1 r1 l 1 l_1 l1 r 2 r_2 r2 l 2 l_2 l2匹配,而是 r 1 r_1 r1 l 2 l_2 l2 r 2 r_2 r2 l 1 l_1 l1匹配,我们可以比较 max ⁡ { r 1 , l 1 } + max ⁡ { r 2 , l 2 } \max\{r_1,l_1\}+\max\{r_2,l_2\} max{r1,l1}+max{r2,l2} max ⁡ { r 1 , l 2 } + max ⁡ { r 2 , l 1 } \max\{r_1,l_2\}+\max\{r_2,l_1\} max{r1,l2}+max{r2,l1}的大小。

不妨设 r 1 > l 1 r_1>l_1 r1>l1(因为可以把所有人的左右手一起互换,但不能只换一部分),则 r 1 > l 2 r_1>l_2 r1>l2,那么:
max ⁡ { r 1 , l 1 } + max ⁡ { r 2 , l 2 } − max ⁡ { r 1 , l 2 } − max ⁡ { r 2 , l 1 } \max\{r_1,l_1\}+\max\{r_2,l_2\}-\max\{r_1,l_2\}-\max\{r_2,l_1\} max{r1,l1}+max{r2,l2}max{r1,l2}max{r2,l1}
= r 1 + max ⁡ { r 2 , l 2 } − r 1 − max ⁡ { r 2 , l 1 } =r_1+\max\{r_2,l_2\}-r_1-\max\{r_2,l_1\} =r1+max{r2,l2}r1max{r2,l1}
= max ⁡ { r 2 , l 2 } − max ⁡ { r 2 , l 1 } =\max\{r_2,l_2\}-\max\{r_2,l_1\} =max{r2,l2}max{r2,l1}
分三类:

  • r 2 ≤ l 2 r_2\leq l_2 r2l2
  • l 2 &lt; r 2 ≤ l 1 l_2&lt;r_2\leq l_1 l2<r2l1
  • l 1 &lt; r 2 l_1&lt;r_2 l1<r2

发现 max ⁡ { r 2 , l 2 } − max ⁡ { r 2 , l 1 } ≤ 0 \max\{r_2,l_2\}-\max\{r_2,l_1\}\leq 0 max{r2,l2}max{r2,l1}0,即第二种方法不比第一种方法优。

(这个证明其实不严谨,但是比较好理解)

代码

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;

#define MAXN 100000
int N;
int Left[MAXN+5],Right[MAXN+5];

int main(){
    scanf("%d",&N);
    for(int i=1;i<=N;i++)
        scanf("%d%d",Left+i,Right+i);
    sort(Left+1,Left+N+1);
    sort(Right+1,Right+N+1);
    long long Ans=N;//每个人还要占一个位置
    for(int i=1;i<=N;i++)
        Ans+=max(Left[i],Right[i]);
    printf("%I64d",Ans);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值