整数区间问题

【题目描述】 

我们定义一个整数区间[a,b],a,b是一个从a开始至b 结束的连续整数的集合。编一个程序,对给定的 n个区间,找出满足下述条件的所含元素个数最少的集合中元素的个数:对于所给定的每一个区间,都至少有两个不同的整数属于该集合。(1<=n<=10000,  0<=a<=b<=1000)

输入输出格式:

输入:第一行一个正整数n,接下来有n行,每行给定一个区间的a,b值

输出:一个正整数,即满足条件的集合所包含的最少元素个数                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              

输入输出样例

输入:           输出:

4                  4

3 6

2 4

0 2

4 7

【算法分析】

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

也不知道哪个OJ有这个题目,所以不知道代码对不对

 1 #include <iostream>
 2 #include <vector>
 3 #include <algorithm>
 4 using namespace std;
 5 struct s
 6 {
 7     int l,r;
 8 };
 9 
10 bool vv(const s &a,const s &b)
11 {
12     return a.r < b.r;
13 }
14 int main()
15 {
16     int n;
17     cin>>n;
18     vector <s> v(n);
19     for (int i = 0; i < n;i++)
20     {
21         cin>>v[i].l>>v[i].r;
22     }
23     vector <int> aim;
24     sort(v.begin(),v.end(),vv);
25     for (int i = 0; i < n;i++)
26     {
27         int num = 0;
28         bool flag = 0;
29         for (int j = v[i].l; j <= v[i].r;j++)
30         {
31             if (find(aim.begin(),aim.end(),j) != aim.end())
32             {
33                 num++;
34                 if ( *find(aim.begin(),aim.end(),j) == v[i].r)
35                 flag =1;
36             }
37         }
38         if (num == 0)
39         {
40             aim.push_back(v[i].r);
41             aim.push_back(v[i].r-1);
42         }
43         else if (num == 1 && flag ==0)
44         {
45             aim.push_back(v[i].r);
46         }
47         else if (num == 1 &&flag ==1)
48             aim.push_back(v[i].r-1);
49     }
50     cout<<aim.size()<<endl;
51     return 0;
52 }

 

转载于:https://www.cnblogs.com/hufeiya/archive/2013/06/03/3115900.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值