贪心-区间问题

拜拜、爱过 提交于 2020-02-21 22:21:24

一:区间选点

题目:

给定N个闭区间[ai,bi],请你在数轴上选择尽量少的点,使得每个区间内至少包含一个选出的点。

输出选择的点的最小数量。

位于区间端点上的点也算作区间内。

输入格式

第一行包含整数N,表示区间数。

接下来N行,每行包含两个整数ai,biai,bi,表示一个区间的两个端点。

输出格式

输出一个整数,表示所需的点的最小数量。

数据范围

1N1051≤N≤105,
109aibi109−109≤ai≤bi≤109

输入样例:

3
-1 1
2 4
3 5

输出样例:

2解析:

 

 代码:

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 const int N = 1e5+10;
 5 
 6 struct Range{
 7     int l, r;
 8     bool operator < (const Range& t){
 9         return r < t.r;
10     }
11 }range[N];
12 
13 int main(){
14     int n;cin >> n;
15     for(int i = 0;i < n;++i) cin >> range[i].l >> range[i].r;
16     sort(range, range+n);
17     int ans = 0; 
18     int last = -0x3f3f3f3f;
19     for(int i = 0;i < n;++i)
20         if(range[i].l > last){
21             ++ans;
22             last = range[i].r;
23         }
24     cout << ans << endl;
25     return 0;
26 }
View Code

 

二:最大不相交区间数量

题目:

给定N个闭区间[ai,bi],请你在数轴上选择若干区间,使得选中的区间之间互不相交(包括端点)。

输出可选取区间的最大数量。

输入格式

第一行包含整数N,表示区间数。

接下来N行,每行包含两个整数ai,biai,bi,表示一个区间的两个端点。

输出格式

输出一个整数,表示可选取区间的最大数量。

数据范围

1N1051≤N≤105,
109aibi109−109≤ai≤bi≤109

输入样例:

3
-1 1
2 4
3 5

输出样例:

2
分析:

 

 

代码:

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 const int N = 1e5+10;
 5 
 6 struct Range{
 7     int l, r;
 8     bool operator < (const Range& t){
 9         return r < t.r;
10     }
11 }range[N];
12 
13 int main(){
14     int n;cin >> n;
15     for(int i = 0;i < n;++i) cin >> range[i].l >> range[i].r;
16     sort(range, range+n);
17     int ans = 0; 
18     int last = -0x3f3f3f3f;
19     for(int i = 0;i < n;++i)
20         if(range[i].l > last){
21             ++ans;
22             last = range[i].r;
23         }
24     cout << ans << endl;
25     return 0;
26 }
View Code

 

三:区间分组

题目:

给定N个闭区间[ai,bi],请你将这些区间分成若干组,使得每组内部的区间两两之间(包括端点)没有交集,并使得组数尽可能小。

输出最小组数。

输入格式

第一行包含整数N,表示区间数。

接下来N行,每行包含两个整数ai,biai,bi,表示一个区间的两个端点。

输出格式

输出一个整数,表示最小组数。

数据范围

1N1051≤N≤105,
109aibi109−109≤ai≤bi≤109

输入样例:

3
-1 1
2 4
3 5

输出样例:

2分析:

 

 代码:

 1 #include <iostream>
 2 #include <algorithm>
 3 #include <queue>
 4 using namespace std;
 5 
 6 const int N = 1e5+10;
 7 
 8 struct Interval{
 9     int l, r;
10     bool operator< (const Interval& t){
11         return l < t.l;
12     }
13 }inter[N];
14 
15 int main(){
16     int n;cin >> n;
17     for(int i = 1;i <= n;++i) cin >> inter[i].l >> inter[i].r ;
18     
19     sort(inter+1, inter+n+1);//按照左端点排序
20     
21     priority_queue<int, vector<int>, greater<int>> pq;//存储每一组的max_r
22     for(int i = 1;i <= n;++i){
23         auto t = inter[i];
24         if(pq.empty() || t.l <= pq.top())
25             pq.push(t.r);
26         else{
27             pq.pop();
28             pq.push(t.r);
29         }
30     }
31     cout << pq.size() << endl;
32     return 0;
33 }
View Code

 

四:区间覆盖

题目:

给定N个闭区间[ai,bi]以及一个线段区间[s,t],请你选择尽量少的区间,将指定线段区间完全覆盖。

输出最少区间数,如果无法完全覆盖则输出-1。

输入格式

第一行包含两个整数s和t,表示给定线段区间的两个端点。

第二行包含整数N,表示给定区间数。

接下来N行,每行包含两个整数ai,biai,bi,表示一个区间的两个端点。

输出格式

输出一个整数,表示所需最少区间数。

如果无解,则输出-1。

数据范围

1N1051≤N≤105,
109aibi109−109≤ai≤bi≤109,
109st109−109≤s≤t≤109

输入样例:

1 5
3
-1 3
2 4
3 5

输出样例:

2分析:

 

 代码:

 1 #include <iostream>
 2 #include <algorithm>
 3 using namespace std;
 4 
 5 const int N = 1e5+10;
 6 
 7 struct Interval{
 8     int l, r;
 9     bool operator< (const Interval& t){
10         return l < t.l;
11     }
12 }inter[N];
13 
14 int main(){
15     int st, ed;cin >> st >> ed;
16     int n;cin >> n;
17     for(int i = 1;i <= n;++i) cin >> inter[i].l >> inter[i].r;
18     
19     sort(inter+1, inter+n+1);
20     
21     int ans = 0;
22     for(int i = 1;i <= n;++i){
23         int j = i;
24         int r = -0x3f3f3f3f;
25         //在所有 l <= st 的区间中找到最靠的
26         while(j <= n && inter[j].l <= st){
27             r = max(r, inter[j].r);
28             ++j;
29         }
30         //如果最靠右的小于st无解
31         if(r < st){
32             cout << "-1" << endl;
33             return 0;
34         }
35         
36         ++ans;
37         
38         if(r >= ed){
39             cout << ans << endl;
40             return 0;
41         }
42         
43         st = r;
44         i = j - 1;
45     }
46     cout << -1 << endl;
47     return 0;
48 }
View Code

 

 

end

 
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!