CF513D Social Circles

版权声明:本文为博主原创文章,不管你喜不喜欢都请在注明作者后转载~( ̄▽ ̄~) https://blog.csdn.net/C20190102/article/details/82942235

题目

传送门

题目大意

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

思路

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

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

不妨设 r 1 > l 1 r_1>l_1 (因为可以把所有人的左右手一起互换,但不能只换一部分),则 r 1 > l 2 r_1>l_2 ,那么:
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\}
= 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\}
= max { r 2 , l 2 } max { r 2 , l 1 } =\max\{r_2,l_2\}-\max\{r_2,l_1\}
分三类:

  • r 2 l 2 r_2\leq l_2
  • l 2 < r 2 l 1 l_2<r_2\leq l_1
  • l 1 < r 2 l_1<r_2

发现 max { r 2 , l 2 } max { r 2 , l 1 } 0 \max\{r_2,l_2\}-\max\{r_2,l_1\}\leq 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);
}

猜你喜欢

转载自blog.csdn.net/C20190102/article/details/82942235