算法竞赛入门经典:第八章 高效算法设计 8.17 贪心之选择不相交区间
2015-08-19 09:21
218 查看
/* 选择不相交区间: 数轴上有n个开区间(ai,bi)。尽量选择多个区间,使得这些区间两两没有公共点 分析: 假设有两个区间x,y。区间x完全包含y。应选x。 按照bi从小到大的顺序给区间排序。 贪心策略: 一定要选第一个区间? 区间排成:b1<=b2<=b3... 情况1: a1>a2,区间2包含区间1,此时应选区间1,a1>ai,不选i 情况2: a1<=a2<=a3,区间1与区间2完全不相交: 相交 :如果不选区间2,,黑色部分无影响,区间1有效部分变成灰色部分,被区间2包含,所以区间2不能选。不能因为选任何区间放弃 区间1,所以选择区间1. 实现: 选择区间1后,需要把所有和区间1相交的区间排除在外,需要记录上一个被选择的区间编号。排序后只需要扫描一次即可完成贪心过程 输入: 12 1 3 3 4 0 7 3 8 15 19 15 20 10 15 8 18 6 12 5 10 4 14 2 9 输出: 5 */ /* 关键: 1 通过区间的右值进行比较 bool operator < (const Section& sec)//自定义比较函数,以右区间进行比较 { return iEnd < sec.iEnd; } 2 if(sec[i].iBeg >= sec[iCur].iEnd)//或者后区间的左值>=前区间的右值,符合 */ #include <stdio.h> #include <algorithm> #define MAXSIZE 1024 using namespace std; typedef struct Section { bool operator < (const Section& sec)//自定义比较函数,以右区间进行比较 { return iEnd < sec.iEnd; } int iBeg; int iEnd; }Section; int selectDisjointSection(Section* sec,int n) { int iCur = 0; int iCount = 1; int i = 1; for(int i = 1 ; i < n ; i++) { if(sec[i].iBeg >= sec[iCur].iEnd)//或者后区间的左值>=前区间的右值,符合 { iCur = i; iCount++; } } return iCount; } void process() { int n; while(EOF != scanf("%d",&n)) { Section sec[MAXSIZE]; for(int i = 0 ; i < n ; i++) { scanf("%d %d",&sec[i].iBeg,&sec[i].iEnd); } sort(sec,sec+n); printf("%d\n",selectDisjointSection(sec,n)); } } int main(int argc,char* argv[]) { process(); getchar(); return 0; }
相关文章推荐
- Welcome to the Real World
- TCP建立连接与释放连接过程中的几个问题
- 有史以来最简单的MVC 例子--IT 攻城狮必看!
- 有史以来最简单的MVC 例子--IT 攻城狮必看!
- poj-3126-Prime Path-BFS
- 算法竞赛入门经典:第八章 高效算法设计 8.16贪心之乘船问题
- Fight Repetition
- NSPredicate的用法
- NSPredicate的用法
- 一个妹子图应用客户端android源码
- Android开发系列6 x86模拟器 Genymotion使用
- javascript 使用for循环时该注意的问题-附问题总结
- Go使用goquery获取url小实例
- 最大record对应数据的取得
- OpenGL深度测试带来的问题----Z冲突
- 词向量的kmeans词聚类实现
- UITableView不弹动,分割线颜色,cell的高度
- Java 树父节点递归获取树子节点
- unity使用抽象工厂模式
- Android连接MS SQLServer 数据库2005-2014