区间贪心

区间贪心

思路:将所有区间先按左端点从大到小排序,再按右端点从小到大排序,从第一个区间开始,记录当前区间的左端点位置lateX,遍历区间数组,如果当前区间的右端点小于lateX, 说明当前区间与上一个区间不相交,将计数器加一,更新lateX为当前区间左端点的值。

模板代码:

 1 // 区间贪心
 2 #include <stdio.h>
 3 #include <stdlib.h>
 4 #include <algorithm>
 5 using namespace std;
 6 
 7 const int maxn = 110;
 8 
 9 // 定义一个结构体存储所有区间
10 struct Inteval{
11     int x, y;        // 开区间左右端点
12 }I[maxn];
13 
14 // 比较函数
15 bool cmp(Inteval a, Inteval b)
16 {
17     if (a.x != b.x)
18         return a.x > b.x;            // 先按左端点从大到小排序
19     else 
20         return a.y < b.y;            // 再按右端点从小到大排序
21 }
22 
23 int main()
24 {
25     freopen("in.txt", "r", stdin);
26     int n;
27      // 读取数据
28     while (scanf("%d", &n), n != 0)
29     {
30         for (int i = 0; i < n; i++)
31         {
32             scanf("%d %d", &I[i].x, &I[i].y);
33         }
34 
35         // 排序
36         sort(I, I + n, cmp);
37             
38         // 统计不相交区间的个数
39         // ant存储个数, lateX存储最近的X
40         int ant = 1, lateX = I[0].x;
41 
42         // 遍历这个数组
43         for (int i = 1; i < n; i++)
44         {
45             if (I[i].y <= lateX)
46             {
47                 ant++;
48                 lateX = I[i].x;            // 更新lateX的值
49             }
50         }
51         printf("%d\n", ant);
52     }
53 
54     fclose(stdin);
55     return 0;
56 }

应用区间贪心算法的另一种题目形式:

区间贪心

 

 这题的算法思路其实和上题是一样,大区间包含小区间只考虑小区间的个数,因为在小区间中一定存在于大区间中;区间相交只需选取其中一个区间,所以也变成了求最大不相交区间的个数的问题,但是因为这题的区间是闭区间,所以上面的 I[i].y <= lateX 要改成I[i].y < lateX 。

 

 本博客内容大部分引用 胡凡的《算法笔记》

上一篇:Latex如何自定义无序列表符号


下一篇:Latex 矢量图 文字嵌入方法