1. 程式人生 > >CF513D Social Circles

CF513D Social Circles

文章目錄

題目

傳送門

題目大意

你請了N(N105)N(N\leq 10^5)個客人吃飯,它們的椅子需要圍成一個或多個圈,但是客人們都有些害羞,第ii個客人希望他的左手邊至少有lil_i個空椅子,右手邊至少有rir_i個空椅子,問你最少需要多少個椅子。注意:客人會對自己感到害羞,也就是說,就算他所在的椅子圈只有他一個人,也要滿足上述條件。

思路

肯定要讓兩個客人的左右手匹配得越多越好,也就是說要最小化max{rj,li}\max\{r_j,l_i\},如果你足夠貪心,直接可以想到:分別按左右手排序,最大的左手和最大的右手匹配,以此類推,然後你就AC

了。

排完序後,假如不是r1r_1l1l_1r2r_2l2l_2匹配,而是r1r_1l2l_2r2r_2l1l_1匹配,我們可以比較max{r1,l1}+max{r2,l2}\max\{r_1,l_1\}+\max\{r_2,l_2\}max{r1,l2}+max{r2,l1}\max\{r_1,l_2\}+\max\{r_2,l_1\}的大小。

不妨設r1>l1r_1>l_1(因為可以把所有人的左右手一起互換,但不能只換一部分),則r

1>l2r_1>l_2,那麼: max{r1,l1}+max{r2,l2}max{r1,l2}max{r2,l1}\max\{r_1,l_1\}+\max\{r_2,l_2\}-\max\{r_1,l_2\}-\max\{r_2,l_1\} =r1+max{r2,l2}r1max{r2,l1}=r_1+\max\{r_2,l_2\}-r_1-\max\{r_2,l_1\} =max{r2,l2}max{r2,l1}=\max\{r_2,l_2\}-\max\{r_2,l_1\} 分三類:

  • r2l2r_2\leq l_2
  • l2<r2l1l_2<r_2\leq l_1
  • l1<r2l_1<r_2

發現max{r2,l2}max{r2,l1}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);
}