区间覆盖全部类型及部分精选习题汇总详解(贪心策略)

内容如下:

1)区间完全覆盖问题

问题描述:给定一个长度为m的区间,再给出n条线段的起点和终点(注意这里是闭区间),求最少使用多少条线段可以将整个区间完全覆盖

样例:

区间长度8,可选的覆盖线段[2,6],[1,4],[3,6],[3,7],[6,8],[2,4],[3,5]

解题过程:

1将每一个区间按照左端点递增顺序排列,拍完序后为[1,4][2,4][2,6][3,5][3,6][3,7][6,8]

2设置一个变量表示已经覆盖到的区域。再剩下的线段中找出所有左端点小于等于当前已经覆盖到的区域的右端点的线段中,右端点最大的线段在加入,直到已经覆盖全部的区域

3过程:

假设第一步加入[1,4],那么下一步能够选择的有[2,6][3,5][3,6][3,7],由于7最大,所以下一步选择[3,7],最后一步只能选择[6,8],这个时候刚好达到了8退出,所选区间为3

4贪心证明:

需要最少的线段进行覆盖,那么选取的线段必然要尽量长,而已经覆盖到的区域之前的地方已经无所谓了,(可以理解成所有的可以覆盖的左端点都是已经覆盖到的地方),那么真正能够使得线段更成的是右端点,左端点没有太大的意义,所以选择右端点来覆盖

2)最大不相交覆盖

问题描述:给定一个长度为m的区间,再给出n条线段的起点和终点(开区间和闭区间处理的方法是不同,这里以开区间为例),问题是从中选取尽量多的线段,使得每个线段都是独立的,就是不和其它有任何线段有相交的地方


样例:

区间长度8,可选的覆盖线段[2,6],[1,4],[3,6],[3,7],[6,8],[2,4],[3,5]

解题过程:

对线段的右端点进行升序排序,每加入一个线段,然后选择后面若干个(也有可能是一个)右端点相同的线段,选择左端点最大的那一条,如果加入以后不会跟之前的线段产生公共部分,那么就加入,否则就继续判断后面的线段

1排序:将每一个区间按右端点进行递增顺序排列,拍完序后为[1,4][2,4][2,6][3,5][3,6][3,7][6,8]

2第一步选取[2,4],发现后面只能加入[6,8],以区间的个数为2


贪心证明:因为需要尽量多的独立的线段,所以每个线段都尽可能的小,对于同一右端点,左端点越大,线段长度越小。那么为什么要对右端点进行排序呢?如果左端点进行排序,那么右端点是多少并不知道,那么每一条线段都不能对之前所有的线段进行一个总结,那么这就明显不满足贪心的最有字结构了。

3)区间选点问题

问题描述:给定一个长度为m的区间,再给出n条线段和这n条线段需要满足的要求(要求是这n条线段上至少有的被选择的点的个数),问题是整个区间内最少选择几个点,使其满足每一条线段的要求.

样例:略

解题过程:将每个线段按照终点坐标进行递增排序,相同终点的前点坐标大的在前面,一个个将其满足

贪心证明:要想使得剩下的线段上选择的点最少,那么就应该尽量使得已经选择了的点尽量能在后面的线段中发挥作用,而我们是从左往右选择线段的,那么要使得选取的点能满足后面线段的要求,那么必须是从线段的有端点开始选点,那么问题(2)一样涉及到一个问题,如果是按照线段的左端点对线段进行排序的话,不知道右端点的话,每一条线段都不能对之前已经操作过的所有线段进行一个总结,那么这就同样不满足贪心算法的最优子结构性质了。

可以解决的实际问题:数轴上面有n个闭区间[a,b],取尽量少的点,使得每个区间内都至少有一个点(不同区间内含的点可以是同一个)

实例(类似第一种区间覆盖,只不过求最大值)

三个农民每天清晨5点起床,然后去牛棚给3头牛挤奶。第一个农民在300时刻(从5点开始计时,秒为单位)给他的牛挤奶,一直到1000时刻。第二个农民在700时刻开始,在 1200时刻结束。第三个农民在1500时刻开始2100时刻结束。期间最长的至少有一个农民在挤奶的连续时间为900秒(从300时刻到1200时刻),而最长的无人挤奶的连续时间(从挤奶开始一直到挤奶结束)为300时刻(从1200时刻到1500时刻)。  你的任务是编一个程序,读入一个有N个农民(1 <= N <= 5000)挤N头牛的工作时间列表,计算以下两点(均以秒为单位):  最长至少有一人在挤奶的时间段。  最长的无人挤奶的时间段。(从有人挤奶开始算起)

Input

Line 1:  一个整数N。  Lines 2..N+1:  每行两个小于1000000的非负整数,表示一个农民的开始时刻与结束时刻。 

Output

一行,两个整数,即题目所要求的两个答案。

Sample Input

3
300 1000
700 1200
1500 2100

Sample Output

900 300

参考代码:

[cpp] view plaincopy
  1. //算法思想:区间覆盖,先排序,总共就两种情况。  
  2. #include<iostream>  
  3. #include<stdio.h>  
  4. #include<fstream>  
  5. #include<algorithm>  
  6. using namespace std;  
  7. #define Max(a,b) a>b?a:b  
  8. typedef struct  
  9. {  
  10.   int s_time;  
  11.   int e_time;  
  12. }D_farmers;  
  13. D_farmers df[5001];  
  14. int n;  
  15. bool cmp(D_farmers a,D_farmers b)//起始时间的升序排序  
  16. {  
  17.     return a.s_time<b.s_time||(a.s_time==b.s_time&&a.e_time<b.e_time);  
  18. }  
  19. int main()  
  20. {  
  21.     ifstream fin("milk2.in");  
  22.     ofstream fout("milk2.out");  
  23.     int i,max1_t=0,max2_t=0,s_max,t_max;//s_max和t_max分别记录最大起始时间和结束时间  
  24.     fin>>n;  
  25.     for(i=0;i<n;i++)  
  26.         fin>>df[i].s_time>>df[i].e_time;  
  27.   
  28.     sort(df,df+n,cmp);//升序排序  
  29.     s_max=df[0].s_time;  
  30.     t_max=df[0].e_time;  
  31.     max1_t=df[0].e_time-df[0].s_time;  
  32.     //max2_t=df[0].s_time;  
  33.   
  34.     for(i=1;i<n;i++)  
  35.     {  
  36.      if(t_max>=df[i].s_time&&df[i].e_time>=t_max)//前一个结束时间大于当前起始时间,更新新的截至时间,  
  37.         t_max=df[i].e_time;  
  38.      else if(t_max<df[i].s_time)//前一个结束时间小于当前起始时间,进行判断比较  
  39.       {  
  40.          //cout<<t_max<<endl;  
  41.          max1_t=Max(t_max-s_max,max1_t);  
  42.          //cout<<max1_t<<endl;  
  43.          max2_t=Max(df[i].s_time-t_max,max2_t);  
  44.          s_max=df[i].s_time;  
  45.          t_max=df[i].e_time;  
  46.       }  
  47.   
  48.     }  
  49.     //cout<<max1_t<<" "<<max2_t<<endl;  
  50.     fout<<max1_t<<" "<<max2_t<<endl;  
  51.     return 0;  
  52. }  

以下内容复制于http://blog.csdn.net/dgq8211/article/details/7534776


先来看看什么是区间选点问题



数轴上有n个闭区间[ai,bi]。取尽量少的点,使得每个区间内都至少有一个点(不同区间内含的点可以是同一个)。

贪心策略:

按照b1<=b2<=b3…(b相同时按a从大到小)的方式排序排序,从前向后遍历,当遇到没有加入集合的区间时,选取这个区间的右端点b。

证明:

为了方便起见,如果区间i内已经有一个点被取到,我们称区间i被满足。

1、首先考虑区间包含的情况,当小区间被满足时大区间一定被满足。所以我们应当优先选取小区间中的点,从而使大区间不用考虑。

      按照上面的方式排序后,如果出现区间包含的情况,小区间一定在大区间前面。所以此情况下我们会优先选择小区间。

      则此情况下,贪心策略是正确的。

2、排除情况1后,一定有a1<=a2<=a3……。


      对于区间1来说,显然选择它的右端点是明智的。因为它比前面的点能覆盖更大的范围。

      从而此情况下,贪心策略也是正确的。


[cpp] view plaincopy
  1. #include <stdio.h>  
  2. #include <algorithm>  
  3. using namespace std;  
  4. struct Extent  
  5. {  
  6.     int a,b;  
  7.     bool operator < (const Extent& S)const  
  8.     {  
  9.         return b < S.b || b == S.b && a > S.a;  
  10.     }  
  11. }A[10002];  
  12. int main()  
  13. {  
  14.     int z,n,cnt,end;  
  15.     scanf("%d",&z);  
  16.     while(z--)  
  17.     {  
  18.         cnt = 0;  
  19.         end = -1;  
  20.         scanf("%d",&n);  
  21.         for(int i=0;i<n;i++)  
  22.             scanf("%d%d",&A[i].a,&A[i].b);  
  23.         sort(A,A+n);  
  24.         for(int i=0;i<n;i++)  
  25.         {  
  26.             if(end < A[i].a)  
  27.             {  
  28.                 end = A[i].b;  
  29.                 cnt++;  
  30.             }  
  31.         }  
  32.         printf("%d\n",cnt);  
  33.     }  
  34.     return 0;  
  35. }  


例题:http://acm.nyist.net/JudgeOnline/problem.php?pid=287

Radar Installation
Time Limit: 1000MS Memory Limit: 10000K
Total Submissions: 38208 Accepted: 8483

Description

Assume the coasting is an infinite straight line. Land is in one side of coasting, sea in the other. Each small island is a point locating in the sea side. And any radar installation, locating on the coasting, can only cover d distance, so an island in the sea can be covered by a radius installation, if the distance between them is at most d.

We use Cartesian coordinate system, defining the coasting is the x-axis. The sea side is above x-axis, and the land side below. Given the position of each island in the sea, and given the distance of the coverage of the radar installation, your task is to write a program to find the minimal number of radar installations to cover all the islands. Note that the position of an island is represented by its x-y coordinates.

Figure A Sample Input of Radar Installations


Input

The input consists of several test cases. The first line of each case contains two integers n (1<=n<=1000) and d, where n is the number of islands in the sea and d is the distance of coverage of the radar installation. This is followed by n lines each containing two integers representing the coordinate of the position of each island. Then a blank line follows to separate the cases.

The input is terminated by a line containing pair of zeros

Output

For each test case output one line consisting of the test case number followed by the minimal number of radar installations needed. "-1" installation means no solution for that case.

Sample Input

3 2
1 2
-3 1
2 11 2
0 20 0

Sample Output

Case 1: 2
Case 2: 1

Source

Beijing 2002

题目的意思就是给你一个坐标轴,雷达在x轴上,岛屿分布在x轴上方,给你岛屿的坐标以及雷达的最大扫描面积,求最少用几个雷达可以将所有的岛屿覆盖!


思路:

以岛为圆心,以d为半径画圆(d是雷达的辐射半径),其与x轴相交的区间为一个区  这样就变成了在区间内找最少的点问题了


[cpp] view plaincopy
  1. #include<iostream>  
  2. #include<cmath>  
  3. using namespace std;  
  4. typedef struct  
  5. {  
  6.     double l,r;  
  7. }in;  
  8. int cmp(const void *a, const void *b)  
  9. {  
  10.     return (*(in *)a).l >= (*(in *)b).l ? 1:-1;  
  11. }  
  12. int main()  
  13. {  
  14.     int n,d,i,x,y,sw,re,count = 1;  
  15.     double pre;  
  16.     in p[1000];  
  17.     while(1)  
  18.     {  
  19.         cin>>n>>d;  
  20.         if(n == 0 && d==0) break;  
  21.         sw = 1;  
  22.         for(i=0;i<n;i++)  
  23.         {  
  24.             cin>>x>>y;  
  25.             if(d>=y&&sw==1)  
  26.             {  
  27.                 p[i].l = x-sqrt((double)d*d - (double)y*y);  
  28.                 p[i].r = x+sqrt((double)d*d - (double)y*y);  
  29.             }  
  30.             else  
  31.             {  
  32.                 sw = 0;  
  33.             }  
  34.         }  
  35.         if(sw == 0)  
  36.         {  
  37.             cout<<"Case "<<count++<<": "<<-1<<endl;  
  38.             continue;  
  39.         }  
  40.         qsort(p,n,sizeof(in),cmp);   
  41.         re = 1;  
  42.         pre = p[0].r;  
  43.         for(i=1;i<n;i++)  
  44.         {  
  45.             if(p[i].l>pre)  
  46.             {  
  47.                 re++;  
  48.                 pre = p[i].r;  
  49.             }  
  50.             else  
  51.             {  
  52.                 if(p[i].r<pre)  
  53.                 {  
  54.                     pre = p[i].r;  
  55.                 }  
  56.             }  
  57.         }  
  58.         cout<<"Case "<<count++<<": "<<re<<endl;  
  59.     }  
  60.     return 0;  
  61. }  


区间均取最少2个点的问题:

给定一个大区间[a,b],再给出几个小区间 ,找出满足下述条件的所含元素个数最少的集合的个数,该集合满足

——对于给定的每一个区间,都至少有两个不同的整数属于该集合。

本题数据规模较大,用搜索做会超时,而动态规划无从下手。考虑贪心算法。题目意思是要找一个集合,该集合中的数的个数既要少又要和所给定的所有区间都有2个点的交集。(每个区间至少有两个该集合中的数)。我们可以从所给的区间中选数,为了选尽量少的数,应该使所选的数和更多的区间有交集这就是贪心的标准。一开始将所有区间按照右端点从小到大排序。从第一个区间开始逐个向后检查,看所选出的数与所查看的区间有无交集,有两个则跳过,只有一个数相交,就从当前区间中选出最大的一个数(即右端点),若无交集,则从当前区间选出两个数,就(右端点,右端点-1),直至最后一个区间。

[cpp] view plaincopy
  1. #include<stdio.h>  
  2. #include<string.h>  
  3. #include<stdlib.h>  
  4. struct prince  
  5. {     
  6.     int left,right;//区间左右端点       
  7. }a[10000];  
  8. int n;  
  9. int result;//存放结果中的数   
  10. int cmp(const void *a,const void *b)  
  11. {     
  12.     return (*(prince *)a).right-(*(prince *)b).right;     
  13. }  
  14. int work()  
  15. {  
  16.     qsort(a+1,n,sizeof(a[0]),cmp);//按区间右端点由小到大排序   
  17.     int i;  
  18.     int a1,a2;  
  19.     a1=a[1].right-1;a2=a[1].right;result=2;  
  20.     for(i=2;i<=n;i++)      
  21.     {  
  22.         if(a[i].left<=a1&& a[i].right>=a2)continue;//完全包含的情况下 其区间的2点就是上次的2点 直接跳过  
  23.     if (a[i].left>a2 )//完全不包含  则要添加进去2点  
  24.     {  
  25.         a1=a[i].right-1;a2=a[i].right;result=result+2;  
  26.     }  
  27.     if (a[i].left>a1 && a[i].right>a2 && a[i].left<=a2)      
  28.     {  
  29.         a1=a2;a2=a[i].right;result++;}//只包含一个     
  30.     }     
  31.     return result;    
  32. }  
  33.   
  34. int main()  
  35. {  
  36.     scanf("%d",&n);  
  37.     int i;  
  38.     for(i=1;i<=n;i++)      
  39.         scanf("%d %d",&a[i].left,&a[i].right);  
  40.    printf("%d\n",work());     
  41.     return 0;  
  42. }  

Problem 1230 区间相交问题 

http://acm.fzu.edu.cn/problem.php?pid=1230

 Problem Description

给定 x 轴上 n 个闭区间。去掉尽可能少的闭区间,使剩下的闭区间都不相交。

★算法设计:对于给定的 n 个闭区间,计算去掉的最少闭区间数。

 Input

对于每组输入数据,输入数据的第一行是正整数 n (1<=n<=40,000),表示闭区间数。接下来的 n 行中,每行有 2 个整数,分别表示闭区间的 2 个端点。

 Output

输出计算出的去掉的最少闭区间数。

 Sample Input

310 2015 1020 15

 Sample Output

2





 Source



思路,贪心,按右端点排序,然后从小到大选,第一个肯定要选,区间相交的情况分两种,一种是一个区间被另一个区间所包含,那么选那个区间比较小的那个,为其他区间腾出区间,另外就是不包含的话就以当前区间右端点为基准,直到有区间的左顶点大于它为止,更新当前区间右端点




[cpp] view plaincopy
  1. #include <iostream>  
  2. #include <cstdio>  
  3. #include <algorithm>  
  4. using namespace std;  
  5. const int maxn=40002;  
  6. struct segment  
  7. {  
  8.     int begin, end;  
  9.     segment(int _b=0, int _e=0):begin(_b),end(_e){};  
  10.     inline bool operator<( const segment& ss ) const  
  11.     {//按照区间的右端点排序  
  12.         return end<ss.end || (end==ss.end)&&(begin<ss.begin);  
  13.     }  
  14.     inline void input()  
  15.     {  
  16.         scanf("%d %d",&begin, &end);  
  17.         if(begin>end)//保证左端点值不比右端点大  
  18.             begin^=end, end^=begin, begin^=end;  
  19.     }  
  20. }seg[maxn];  
  21. int main()  
  22. {  
  23.     int n;  
  24.     while(scanf("%d",&n)!=EOF)  
  25.     {  
  26.         int i, res=1, limit;  
  27.         for(i=0; i<n; i++)  
  28.             seg[i].input();  
  29.         sort(seg,seg+n);  
  30.         limit=seg[0].end;  
  31.         for(i=1; i<n; i++)  
  32.         {//seg[i].begin<=limit的所有区间都是相互相交的,因为这些区间必然有公共点limit,即某一个区间的右端点  
  33.             if(seg[i].begin>limit)  
  34.                 res++, limit=seg[i].end;  
  35.         }  
  36.         printf("%d\n",n-res);  
  37.     }  
  38.     return 0;  
  39. }  

Bus

Accepted : 63 Submit : 514
Time Limit : 1000 MS Memory Limit : 65536 KB 

题目描述

小强刚来到长沙这个大城市,发现这里有很多他老家没有的东西,其中一个就是公交车了。小强的家到学校有很多个公交站,每个公交站都有一个英文名字。小强很喜欢坐公交车,但是他有个奇怪的要求,就是公交车的上车站和下车站的英文名字必须是首字母相同的,且不在同一个站上下车,不然小强宁愿走过这个站去搭下一趟车,甚至直接走到学校。给出小强从家里到学校的之间每一个公交站的英文名字,问如果不往回走,小强最多能搭几次公交车?

输入

多组样例,每组样例第一行为非负整数n(n<=1000),表示小强家里到学校之间有n个公交站。接下来n行,每行有一个英文名字,每行不超过100字符。

输出

对于每组样例,输出最多的乘坐次数。

样例输入

4
shaoshan
erzhong
shangxia
dongmen
5
shaoshan
shangxia
ertian
erzhong
dongmen

样例输出

1
2

http://202.197.224.59/OnlineJudge2/index.php/Contest/read_problem/cid/24/pid/1151


和上面那个题一样


思路:按照题意,可以将首字母相同的站当成一个区间。题目就转换成了,从x个区间中,怎样选择让不想交的区间最多。思路是贪心。

代码:

[cpp] view plaincopy
  1. #include <stdio.h>  
  2. #include <algorithm>  
  3. using namespace std;  
  4. struct st  
  5. {  
  6.     int s,e;  
  7. }a[1000002];  
  8. char ch[1002][103];  
  9. bool cmp(st a,st b)  
  10. {  
  11.     if(a.e==b.e)  
  12.         return a.s<b.s;  
  13.     return a.e<b.e;  
  14. }  
  15. int main()  
  16. {  
  17.     int i,j,n;  
  18.     int tm;  
  19.     int w;  
  20.     while(scanf("%d",&n)!=EOF)  
  21.     {  
  22.         tm=0;  
  23.         int s;  
  24.         for(i=0;i<n;i++)  
  25.         {  
  26.             scanf("%s",ch[i]);  
  27.             for(j=0;j<i;j++)  
  28.             {  
  29.                 if(ch[i][0]==ch[j][0])  
  30.                 {  
  31.                     a[tm].s=j;  
  32.                     a[tm++].e=i;  
  33.                 }  
  34.             }  
  35.         }  
  36.         if(tm>0)  
  37.         {  
  38.             s=1;  
  39.             w=a[0].e;  
  40.             for(i=1;i<tm;i++)  
  41.             {  
  42.                 if(a[i].s>w)  
  43.                 {  
  44.                     s++;  
  45.                     w=a[i].e;  
  46.                 }  
  47.             }  
  48.             printf("%d\n",s);  
  49.         }  
  50.         else  
  51.             printf("0\n");  
  52.     }  
  53.     return 0;  
  54. }  

以上内容转自:https://blog.csdn.net/enjoying_science/article/details/41177531



基于贪心算法的几类区间覆盖问题:

(1)区间完全覆盖问题
问题描述:
给定一个长度为m的区间,再给出n条线段的起点和终点(注意这里是闭区间),
求最少使用多少条线段可以将整个区间完全覆盖
样例:
区间长度8,可选的覆盖线段[2,6],[1,4],[3,6],[3,7],[6,8],[2,4],[3,5]
解题过程:
1、将每一个区间按照左端点递增顺序排列,拍完序后为[1,4],[2,4],[2,6],[3,5],
[3,6],[3,7],[6,8]
2、设置一个变量表示已经覆盖到的区域。再剩下的线段中找出所有左端点小于等于当前
已经覆盖到的区域的右端点的线段中,右端点最大的线段在加入,直到已经覆盖全部的区域
3、过程:
假设第一步加入[1,4],那么下一步能够选择的有[2,6],[3,5],[3,6],[3,7],
由于7最大,所以下一步选择[3,7],最后一步只能选择[6,8],这个时候刚好
达到了8退出,所选区间为3
4、贪心证明:
需要最少的线段进行覆盖,那么选取的线段必然要尽量长,而已经覆盖到的区域之前
的地方已经无所谓了,(可以理解成所有的可以覆盖的左端点都是已经覆盖到的地方),
那么真正能够使得线段更成的是右端点,左端点没有太大的意义,所以选择右端点来覆盖

(2)最大不相交覆盖(我总感觉这个算法不对,这不应该和会议安排问题一样吗? 直接按照终点排序再依次选择???)
问题描述:
给定一个长度为m的区间,再给出n条线段的起点和终点(开区间和闭区间处理的方法是
不同,这里以开区间为例),问题是从中选取尽量多的线段,使得每个线段都是独立的,
就是不和其它有任何线段有相交的地方
样例:
区间长度8,可选的覆盖线段[2,6],[1,4],[3,6],[3,7],[6,8],[2,4],[3,5]
解题过程:
对线段的右端点进行升序排序,每加入一个线段,然后选择后面若干个
(也有可能是一个)右端点相同的线段,选择左端点最大的那一条,如果加入以后不会
跟之前的线段产生公共部分,那么就加入,否则就继续判断后面的线段
1、排序:将每一个区间按右端点进行递增顺序排列,拍完序后为[1,4],[2,4],[3,5],[2,6],
[3,6],[3,7],[6,8]
2、第一步选取[2,4],发现后面只能加入[6,8],所以区间的个数为2
3、贪心证明:因为需要尽量多的独立的线段,所以每个线段都尽可能的小,
对于同一右端点,左端点越大,线段长度越小。那么为什么要对右端点进行排序呢?
如果左端点进行排序,那么右端点是多少并不知道,那么每一条线段都不能对之前所有
的线段进行一个总结,那么这就明显不满足贪心的最有字结构了。

(3)区间选点问题
问题描述:
给定一个长度为m的区间,再给出n条线段和这n条线段需要满足的要求
(要求是这n条线段上至少有的被选择的点的个数),问题是整个区间内最少
选择几个点,使其满足每一条线段的要求.
样例:略
解题过程:
将每个线段按照终点坐标进行递增排序,相同终点的前点坐标从大到小排列,
一个个将其满足(每次选择的点为该条线段的右端点)
贪心证明:
要想使得剩下的线段上选择的点最少,那么就应该尽量使得已经选择了的点尽量能
在后面的线段中发挥作用,而我们是从左往右选择线段的,那么要使得选取的点能
满足后面线段的要求,那么必须是从线段的右端点开始选点,那么问题(2)一样涉及
到一个问题,如果是按照线段的左端点对线段进行排序的话,不知道右端点的话,
每一条线段都不能对之前已经操作过的所有线段进行一个总结,那么这就同样不满足
贪心算法的最优子结构性质了。
可以解决的实际问题:数轴上面有n个闭区间[a,b],取尽量少的点,使得每个区间内都
至少有一个点(不同区间内含的点可以是同一个)

应用例题:(貌似不是很简单。。。)
  有一列整数,他的每一个数各不相同,我们不知道有多少个,但我们知道在
某些区间中至少有多少个整数,用区间(L,R,C)来描述,表示整数序列
中至少有C个整数来自子区间[L, R],若干个这样的区间,问这个整数序列的长
度最少能为多少。

 

区间选点算法实现:

复制代码
 1 #include <iostream>
 2 #include <algorithm>
 3 
 4 using namespace std;
 5 
 6 struct line
 7 {
 8     int left;
 9     int right;
10 }a[100];
11 
12 bool cmp(line p, line q)
13 {
14     if(p.right != q.right)
15         return p.right < q.right;
16     return p.left > q.left;
17 }
18 
19 int main()
20 {
21     int n;
22     while(cin >> n)
23     {
24         for(int i = 0; i < n; ++i)
25             cin >> a[i].left >> a[i].right;
26         sort(a, a + n, cmp);
27         int cnt = 0;
28         int end = -1;
29         for(int i = 0; i < n; ++i)
30         {
31             if(end >= a[i].left && end <= a[i].right)
32                 continue;
33             else
34             {
35                 ++cnt;
36                 end = a[i].right;
37             }
38         }
39         cout << cnt << endl;
40     }
41     return 0;
42 }

以上内容转自:https://www.cnblogs.com/dongsheng/archive/2013/04/19/3030444.html



本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/442153.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【POJ - 1328】Radar Installation(贪心+计算几何)安装雷达辐射岛屿

题干&#xff1a;Assume the coasting is an infinite straight line. Land is in one side of coasting, sea in the other. Each small island is a point locating in the sea side. And any radar installation, locating on the coasting, can only cover d distance, so …

【CF#757A】Gotta Catch Em' All!

题干&#xff1a;Bash wants to become a Pokemon master one day. Although he liked a lot of Pokemon, he has always been fascinated by Bulbasaur the most. Soon, things started getting serious and his fascination turned into an obsession. Since he is too young…

【HDU - 4509】湫湫系列故事——减肥记II(合并区间模板 or 离散化标记 or 线段树)

题干&#xff1a;虽然制定了减肥食谱&#xff0c;但是湫湫显然克制不住吃货的本能&#xff0c;根本没有按照食谱行动&#xff01; 于是&#xff0c;结果显而易见… 但是没有什么能难倒高智商美女湫湫的&#xff0c;她决定另寻对策——吃没关系&#xff0c;咱吃进去再运动运动消…

【HDU - 2093】 考试排名(排序+格式输出)

题干&#xff1a;C编程考试使用的实时提交系统&#xff0c;具有即时获得成绩排名的特点。它的功能是怎么实现的呢&#xff1f; 我们做好了题目的解答&#xff0c;提交之后&#xff0c;要么“AC”&#xff0c;要么错误&#xff0c;不管怎样错法&#xff0c;总是给你记上一笔&…

.net core 5 IIS Api网站部署需要注意(同.net 6)

应用程序池&#xff1a;.net clr 版本&#xff1a;无托管代码 2.安装.NET Core SDK和AspNetCoreModule托管模块 此工具要在官网直接下载即可

【HDU - 2087】 剪花布条(直接模拟 or KMP)

题干&#xff1a; 一块花布条&#xff0c;里面有些图案&#xff0c;另有一块直接可用的小饰条&#xff0c;里面也有一些图案。对于给定的花布条和小饰条&#xff0c;计算一下能从花布条中尽可能剪出几块小饰条来呢&#xff1f; Input输入中含有一些数据&#xff0c;分别是成…

webapi自宿主设置本地端口使用https协议

首先&#xff0c;你要申请证书&#xff0c;然后导入到证书里面&#xff1a; 具体步骤&#xff1a;运行–MMC命令&#xff0c;进入如下界面进行设置&#xff1a; 一直点下一步直到完成&#xff0c;然后将证书导入到个人里面 这个时候进入cmd程序运行如下命令&#xff1a; /…

第九届(2018)蓝桥杯 山东省赛解题报告(题目+分析+代码)

1标题&#xff1a;第几天 2000年的1月1日&#xff0c;是那一年的第1天。那么&#xff0c;2000年的5月4日&#xff0c;是那一年的第几天&#xff1f; 注意&#xff1a;需要提交的是一个整数&#xff0c;不要填写任何多余内容。 【答案】&#xff1a;125 2标题&#xff1a;明码 …

Windows下 Python3.7.0 运行环境的搭建 一套操作后就可以使用Python写代码啦~

1.下载Python for windows 废话不说&#xff0c;直接上网址&#xff1a;https://www.python.org/ftp/python/3.5.1/python-3.5.1.exe 2.安装Python for windows 运行安装文件之后&#xff0c;你会看到这个页面&#xff1a;不得不说Python 在 Windows平台下的安装比傻瓜式还傻瓜…

【HDU - 1326】Box of Bricks(模拟水题)

题干&#xff1a;Little Bob likes playing with his box of bricks. He puts the bricks one upon another and builds stacks of different height. Look, Ive built a wall!, he tells his older sister Alice. Nah, you should make all stacks the same height. Then you …

微信公众平台网站开发JS_SDK遇到的bug——wx.config注册提示成功,但部分接口注册失败问题

1 2022-02-23 使用微信公众平台调用扫一扫接口&#xff0c;总是注册不成功 这是进行注册后成功注册的接口提示 尝试注册了以下接口 拥有相关权限 解决办法&#xff1a;猜测失败原因为&#xff1a;子界面进行注册&#xff0c;在父界面进行注册后&#xff0c;成功

c++ 低位在前 高位在后_A股市场:如果股票涨停后第二天“高开低走”,你知道怎么操作才能利益最大化吗?...

(本文由公众号越声策略(yslc188)整理&#xff0c;仅供参考&#xff0c;不构成操作建议。如自行操作&#xff0c;注意仓位控制和风险自负。)如果你的股票涨停后第二天高开低走&#xff0c; 后市怎么操作&#xff1f;简单来讲&#xff0c;高开低走就是开盘价高于上个交易日的收盘…

文件内容查找方式

第一种&#xff0c;使用windows自带的查找工具 搜索工具里面有”高级选项“&#xff0c;选择”文件内容“然后进行搜索即可 第二种&#xff0c;使用命令行 在需要进行搜索的文件夹下使用命令行&#xff1a; Get-ChildItem -Path F:\ -Recurse | Select-String -Pattern &qu…

【HDU - 1301】Jungle Roads(并查集+最小生成树)(内附最小生成树两种算法 克鲁斯特尔算法amp;amp;普里姆算法)

题干&#xff1a; Jungle Roads Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 5505 Accepted Submission(s): 3976 Problem Description The Head Elder of the tropical island of Lagrishan has a proble…

vscode中怎样格式化js代码_[VSCode插件推荐] Bracket Pair Colorizer: 为代码中的括号添上一抹亮色...

在代码编写过程中&#xff0c;各种括号 {[()]} 必不可少。然而&#xff0c;随着代码量的增加&#xff0c;你有没有因为括号的嵌套太多&#xff0c;而导致代码难以阅读&#xff1f;我们来看看下面的代码&#xff0c;在第三行代码的最后部分&#xff0c;连续出现了5个右括号&…

*【HDU - 1506】【POJ - 2559】Largest Rectangle in a Histogram(单调栈或动态规划)

题干&#xff1a; Description A histogram is a polygon composed of a sequence of rectangles aligned at a common base line. The rectangles have equal widths but may have different heights. For example, the figure on the left shows the histogram that consist…

【基础知识】大数据组件HBase简述

HBase是一个开源的、面向列&#xff08;Column-Oriented&#xff09;、适合存储海量非结构化数据或半结构化数据的、具备高可靠性、高性能、可灵活扩展伸缩的、支持实时数据读写的分布式存储系统。 只是面向列&#xff0c;不是列式存储 mysql vs hbase vs clickhouse HMaster …

改变定时器获取传感器频度_广东梅州梅县压力传感器*校对

广东梅州梅县压力传感器*校对看门狗寄存器不会改变或改变不大&#xff0c;如果看门狗寄存器发生了改变或改变很大&#xff0c;则说明系统陷入“死循环”.需要进行出错处理。在工业应用中&#xff0c;严重的干扰有时会破坏中断方式控制字&#xff0c;关闭中断&#xff0c;造成看…

springboot 不响应字段为空_面试官扎心一问:Tomcat 在 SpringBoot 中是如何启动的?...

作者&#xff1a;木木匠 http://my.oschina.net/luozhou/blog/3088908前言我们知道 SpringBoot 给我们带来了一个全新的开发体验&#xff0c;我们可以直接把 web 程序达成 jar 包&#xff0c;直接启动&#xff0c;这就得益于 SpringBoot 内置了容器&#xff0c;可以直接启动&am…

a1708硬盘转接口_资讯:希捷上架新款银河Exos系列机械硬盘,15000转+SAS协议

今日最新消息&#xff0c;希捷上架一款新品希捷银河Exos系列机械硬盘。据悉这款硬盘采用了SAS协议&#xff0c;转速高达15000RPM&#xff0c;目前公布的售价600GB为1899元RMB。据官方介绍这款希捷银河Exos系列机械硬盘为2.5英寸&#xff0c;15mm的厚度&#xff0c;最高的转速可…