AcWing 907. 区间覆盖
给定 N N N个闭区间 [ a i , b i ] [ai,bi] [ai,bi]以及一个线段区间 [ s , t ] [s,t] [s,t],请你选择尽量少的区间,将指定线段区间完全覆盖。
输出最少区间数,如果无法完全覆盖则输出 − 1 -1 −1。
输入格式
第一行包含两个整数 s s s和 t t t,表示给定线段区间的两个端点。
第二行包含整数 N N N,表示给定区间数。
接下来N行,每行包含两个整数 a i , b i ai,bi ai,bi,表示一个区间的两个端点。
输出格式
输出一个整数,表示所需最少区间数。
如果无解,则输出-1。
数据范围
1
≤
N
≤
1
0
5
1 \leq N \leq 10^{5}
1≤N≤105
−
1
0
9
≤
a
i
≤
b
i
≤
1
0
9
-10^{9} \leq a_{i} \leq b_{i} \leq 10^{9}
−109≤ai≤bi≤109
−
1
0
9
≤
s
≤
t
≤
1
0
9
-10^{9} \leq s \leq t \leq 10^{9}
−109≤s≤t≤109
思路
①将所有区间按左端点从小到大排序
②从前往后依次枚举每个区间,在所有能覆盖 s t a r t start start的区间中,选择右端点最大的区间
选完之后将 s t a r t start start更新成右端点的最大值 依次选择区间并更新 s t a r t start start如果最后一次更新的 s t a r t < e n d start < end start<end 无解
代码
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 100010;
int n;
int main() {
scanf("%d", &n);
priority_queue<int, vector<int>, greater<int>>p;
for (int i = 0; i < n; ++i) {
int x; scanf("%d", &x);
p.push(x);
}
LL res = 0;
while (!p.empty()) {
if (p.size() != 1) {
int a = p.top();
p.pop();
int b = p.top();
p.pop();
res += (LL)a + b;
p.push(a + b);
}
else {
p.pop();
}
}
cout << res << endl;
return 0;
}