代码源每日一题(补)社交圈

社交圈

又上网课了,离昆明场多了七天,现在还剩接近20天,抓紧补题了

题目

现在有 \(N\) 个人,每一个人都不想周围的人坐得离他很近,所以在他的左边要放$ L_i$ 张空椅子,右边要放 \(R_i\) 张空椅子,同时每个人自己要坐 \(1\) 张椅子。

现在他们要坐成若干个圈,请问最少要放多少张椅子(包括每个人自己坐的椅子)?

输入格式

第 11 行一个整数 \(N\)

第 22 行至第\(N+1\) 行每行两个整数 \(L_i\)\(R_i\)

输出格式

一个整数,表示最少需要的椅子数量。

样例输入

4
1 2
2 1
3 5
5 3

样例输出

15

数据规模

\(1≤N≤1×10^5\)

\(0≤L_i,R_i≤1×10^9。\)

题目分析

对于第i个人来讲,其右边的距离为:

\[Ans[i]=max(left[i],right[i+1]) \]

也就是说,右边的距离要么是你右边的限制,要么是后一个人左边的限制,答案为

\[ans = \sum_{i=1}^n max(left[i],right[i+1]) \]

对于每一个点来讲,规划好其右边的距离即可,如果考虑成环的话,也不难,由于题目说明了若干个环,所以第一个人左边只要和最后一个人右边成最优解后,再对剩余的人分析,依旧不影响最终结果。

至此,问题化成了如何让左右最相似,对数组分别按左边顺序、右边顺序排序即可。

Accept code

//http://oj.daimayuan.top/course/10/problem/606
//2022-03-29 finish 
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e5+7;
struct Node{
	ll l,r;
	int num;
}a[N],b[N];
bool vis[N];
bool cmp1(Node x,Node y) {
	return x.l < y.l;
}
bool cmp2(Node x,Node y) {
	return x.r < y.r;
}
int main() {
	int n;
	scanf("%d",&n);
	for(int i = 1 ; i <= n ; i++) {
		scanf("%lld%lld",&a[i].l,&a[i].r);
		b[i].l = a[i].l, b[i].r = a[i].r;
		b[i].num = a[i].num = i;
	}
	sort(a+1,a+n+1,cmp1);
	sort(b+1,b+n+1,cmp2);
	ll ans = n;
	for(int i = 1 ; i <= n ; i++) {
		ans += max(a[i].l,b[i].r);
	}
	cout << ans;
}
posted @ 2022-03-29 11:20  seekerHeron  阅读(215)  评论(0)    收藏  举报