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

内容如下:

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,一经查实,立即删除!

相关文章

数据库提示:正在还原中,无法访问 应该怎么办?

Sql语句 restore database 数据库名 with recovery

数据库工具一段时间后打开报错:远程过程调用失败0x800706be

1.原因可能是安装vs时自带更高版本的sql server服务造成的&#xff0c;只需要卸载Microsoft SQL Server 2012 Express LocalDB或 Microsoft SQL Server 2012 LocalDB就行了 2.先安装vs工具&#xff0c;然后安装数据库工具

【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 …

sql语句实现分页查询

2005及以上版本 -- 分页查询&#xff08;通用型&#xff09; select top pageSize * from (select row_number() over(order by sno asc) as rownumber,* from student) temp_row where rownumber>((pageIndex-1)*pageSize);2012及以上版本 select * from student orde…

【51nod-1289】大鱼吃小鱼

题干&#xff1a; 有N条鱼每条鱼的位置及大小均不同&#xff0c;他们沿着X轴游动&#xff0c;有的向左&#xff0c;有的向右。游动的速度是一样的&#xff0c;两条鱼相遇大鱼会吃掉小鱼。从左到右给出每条鱼的大小和游动的方向&#xff08;0表示向左&#xff0c;1表示向右&…

如何通过属性给实体赋值

获取实体属性 Type type family.GetType(); //family为实体对象 PropertyInfo[] infos type.GetProperties(); foreach (PropertyInfo info in infos){info.GetValue(family); //取值info.SetValue(bFamily, info.GetValue(family)); //赋值 }

【CF#801 A.】 Vicious Keyboard(字符串查找,水题)

题干&#xff1a;Tonio has a keyboard with only two letters, "V" and "K". One day, he has typed out a string s with only these two letters. He really likes it when the string "VK" appears, so he wishes to change at most one let…

关于ajax请求400问题解决

ajax请求&#xff1a;400 bad request 原因有两种&#xff1a; 参数不匹配&#xff0c;请求太长 如何解决 针对参数不匹配&#xff0c;只能一一对照 请求太长的话&#xff0c;api最好使用post方式请求&#xff0c;我遇到的问题就是post请求太长&#xff0c;这时候需要给参数…

【uva-673】 Parentheses Balance(括号匹配问题)

题干&#xff1a; You are given a string consisting of parentheses () and []. A string of this type is said to be correct:(a)if it is the empty string(b)if A and B are correct, AB is correct,(c)if A is correct, (A) and [A] is correct.Write a program that ta…

layui前端框架弹出框图标整理

1绿色对勾 2红色 3黄色问号 4黑色小锁 5红色哭脸 6绿色笑脸

【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…

layui 折叠面板使用无效问题

静态折叠面板无法使用 解决方案&#xff1a;layui.js 引用位置应该放在距离layui.use临近的地方 动态设置折叠面板无法点击折叠展开 解决方案&#xff1a;动态加载完界面后&#xff0c;执行下面语句&#xff1a; layui.element.init();

【HDU - 1031 】Design T-Shirt(水题 排序)

题干&#xff1a;Soon after he decided to design a T-shirt for our Algorithm Board on Free-City BBS, XKA found that he was trapped by all kinds of suggestions from everyone on the board. It is indeed a mission-impossible to have everybody perfectly satisfie…

针对标签属性data-**的使用

在网站开发过程中&#xff0c;很多时候需要自定义一些标签属性&#xff0c;可以使用&#xff1a; 在html中&#xff1a; data-**"" 在js代码中取值&#xff1a; var **标签.data("**")

【HDU - 2203】 亲和串 (思维题,可选KMP)

题干&#xff1a;Problem Description人随着岁数的增长是越大越聪明还是越大越笨&#xff0c;这是一个值得全世界科学家思考的问题,同样的问题Eddy也一直在思考&#xff0c;因为他在很小的时候就知道亲和串如何判断了&#xff0c;但是发现&#xff0c;现在长大了却不知道怎么去…

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

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

layui中日期格式化方式

如何对日期进行格式化 layui.util.toDateString(日期值, yyyy-MM-dd HH:mm:ss.fff)

【51NOD - 1523】 非回文(dfs)

题干&#xff1a;一个字符串是非回文的&#xff0c;当且仅当&#xff0c;他只由前p个小写字母构成&#xff0c;而且他不包含长度大于等于2的回文子串。 给出长度为n的非回文串s。请找出字典序比s大的&#xff0c;而且字典序要最小的长度为n的非回文。 Input单组测试数据。 第一…

C# XML字符串与DataTable相互转换

不多说&#xff0c;直接上代码&#xff1a; //DataTable转Xml字符串 public static string ConvertDataTableToXML(DataTable xmlDS){MemoryStream stream null;XmlTextWriter writer null;try{stream new MemoryStream();writer new XmlTextWriter(stream, Encoding.Defa…

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

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