题目
题目大意
你请了 N ( N ≤ 1 0 5 ) N(N\leq 10^5) N(N≤105)个客人吃饭,它们的椅子需要围成一个或多个圈,但是客人们都有些害羞,第 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}−r1−max{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 r2≤l2
- l 2 < r 2 ≤ l 1 l_2<r_2\leq l_1 l2<r2≤l1
- l 1 < r 2 l_1<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);
}