贪心法——区间覆盖问题

区间覆盖问题。数轴上有n个闭区间[ai,bi][a_i, b_i],选择尽量少的区间覆盖一条指定线段[s,t][s,t]。

先进行预处理,将不包含[s,t][s,t]的区间都去掉,然后再按左区间从小到大排序。如果最小区间的左区间大于ss的话,则无解。选取包含ss的右区间最大的区间,该区间的右区间仍然小于下一个区间的左区间,则无解。按照这样的方法一直选择到最后一个区间,如果最后一个区间的右区间小于t<script id="MathJax-Element-454" type="math/tex">t</script>,则无解。否则输出所有区间。

区间覆盖问题实现代码

// 区间数据结构
struct Region {// 左区间int left;// 右区间int right;operator < (const Region &r) {return left < r.left;}
};// 贪心法
// 区间覆盖问题
void region(Region *r, int n, Region target) {// 预处理,将和target有交集的区间提取出来int num = 0;Region re[n];for(int i = 0; i < n; i++) {// 和目标线段无交集if(r[i].left > target.right || r[i].right < target.left) {continue;}re[num++] = r[i];}// 区间是否覆盖完全int isCover = 1;// 处理后无区间if(!num) {isCover = 0;}// 按左区间大小从小到大排序sort(re, re + num);// 当前最大区间Region curMax = re[0];// 记录覆盖区间vector<Region> coverR;// 处理覆盖最左边的问题if(curMax.left > target.left) {isCover = 0;}// 处理覆盖中间问题for(int i = 1; i < num; i++) {// 下一个区间和当前最大区间无交集if(re[i].left > curMax.right) {isCover = 0;break ;}// 覆盖右区间比当前最大区间大,且还能覆盖到目标区间左区间if(re[i].right > curMax.right && re[i].left <= target.left) {curMax.left = re[i].left;curMax.right = re[i].right;} else if(re[i].left > target.left) {coverR.push_back(curMax);// 目标区间左区间设置为最大区间右区间target.left = curMax.right;// 该区间覆盖右区间比最大右区间大if(re[i].right > curMax.right) {curMax.left = re[i].left;curMax.right = re[i].right;}}}// 处理覆盖最右边的问题if(curMax.right < target.right) {isCover = 0;} else {coverR.push_back(curMax);}// 输出if(isCover) {for(int i = 0; i < coverR.size(); i++) {cout << "区间:(" << coverR[i].left << "," << coverR[i].right << ")" << endl;}cout << "区间总数为:" << coverR.size() << endl << endl;} else {cout << "无解。" << endl << endl;}
}

测试主程序

#include <iostream>
#include <algorithm>
#include <vector>using namespace std;// 区间数据结构
struct Region {// 左区间int left;// 右区间int right;operator < (const Region &r) {return left < r.left;}
};// 贪心法
// 区间覆盖问题
void region(Region *r, int n, Region target) {// 预处理,将和target有交集的区间提取出来int num = 0;Region re[n];for(int i = 0; i < n; i++) {// 和目标线段无交集if(r[i].left > target.right || r[i].right < target.left) {continue;}re[num++] = r[i];}// 区间是否覆盖完全int isCover = 1;// 处理后无区间if(!num) {isCover = 0;}// 按左区间大小从小到大排序sort(re, re + num);// 当前最大区间Region curMax = re[0];// 记录覆盖区间vector<Region> coverR;// 处理覆盖最左边的问题if(curMax.left > target.left) {isCover = 0;}// 处理覆盖中间问题for(int i = 1; i < num; i++) {// 下一个区间和当前最大区间无交集if(re[i].left > curMax.right) {isCover = 0;break ;}// 覆盖右区间比当前最大区间大,且还能覆盖到目标区间左区间if(re[i].right > curMax.right && re[i].left <= target.left) {curMax.left = re[i].left;curMax.right = re[i].right;} else if(re[i].left > target.left) {coverR.push_back(curMax);// 目标区间左区间设置为最大区间右区间target.left = curMax.right;// 该区间覆盖右区间比最大右区间大if(re[i].right > curMax.right) {curMax.left = re[i].left;curMax.right = re[i].right;}}}// 处理覆盖最右边的问题if(curMax.right < target.right) {isCover = 0;} else {coverR.push_back(curMax);}// 输出if(isCover) {for(int i = 0; i < coverR.size(); i++) {cout << "区间:(" << coverR[i].left << "," << coverR[i].right << ")" << endl;}cout << "区间总数为:" << coverR.size() << endl << endl;} else {cout << "无解。" << endl << endl;}
}int main() {while(true) {// n个开区间int n;cout << "请输入闭区间的数量(0退出):";cin >> n;if(!n) {break;}// 需要覆盖的线段区间Region target;cout << "需要覆盖的线段区间为:";cin >> target.left >> target.right;Region r[n];for(int i = 0; i < n; i++) {cout << "第" << i + 1 << "个闭区间(x,y)为:";cin >> r[i].left;cin >> r[i].right;}cout << "最少区间能覆盖线段区间[" << target.left << "," << target.right <<"]组合和总数为:" << endl;region(r, n, target);}return 0;
}

输出数据

请输入闭区间的数量(0退出):5
需要覆盖的线段区间为:5 10
第1个闭区间(x,y)为:1 3
第2个闭区间(x,y)为:3 6
第3个闭区间(x,y)为:5 7
第4个闭区间(x,y)为:7 9
第5个闭区间(x,y)为:8 11
最少区间能覆盖线段区间[5,10]组合和总数为:
区间:(5,7)
区间:(7,9)
区间:(8,11)
区间总数为:3请输入闭区间的数量(0退出):3
需要覆盖的线段区间为:5 9
第1个闭区间(x,y)为:1 3
第2个闭区间(x,y)为:1 4
第3个闭区间(x,y)为:2 3
最少区间能覆盖线段区间[5,9]组合和总数为:
无解。请输入闭区间的数量(0退出):3
需要覆盖的线段区间为:5 9
第1个闭区间(x,y)为:10 11
第2个闭区间(x,y)为:12 13
第3个闭区间(x,y)为:14 15
最少区间能覆盖线段区间[5,9]组合和总数为:
无解。请输入闭区间的数量(0退出):5
需要覆盖的线段区间为:5 9
第1个闭区间(x,y)为:6 7
第2个闭区间(x,y)为:7 8
第3个闭区间(x,y)为:8 9
第4个闭区间(x,y)为:9 10
第5个闭区间(x,y)为:10 11
最少区间能覆盖线段区间[5,9]组合和总数为:
无解。请输入闭区间的数量(0退出):5
需要覆盖的线段区间为:5 9
第1个闭区间(x,y)为:1 5
第2个闭区间(x,y)为:5 6
第3个闭区间(x,y)为:5 7
第4个闭区间(x,y)为:8 9
第5个闭区间(x,y)为:9 10
最少区间能覆盖线段区间[5,9]组合和总数为:
无解。请输入闭区间的数量(0退出):5
需要覆盖的线段区间为:5 9
第1个闭区间(x,y)为:1 5
第2个闭区间(x,y)为:5 6
第3个闭区间(x,y)为:5 7
第4个闭区间(x,y)为:5 8
第5个闭区间(x,y)为:6 7
最少区间能覆盖线段区间[5,9]组合和总数为:
无解。请输入闭区间的数量(0退出):0Process returned 0 (0x0)   execution time : 172.044 s
Press any key to continue.

贪心法——区间覆盖问题相关推荐

  1. 贪心法——区间选点问题

    贪心法--区间选点问题 区间选点问题.数轴上有nn个闭区间[ai,bi][a_i, b_i].取尽量少的点,使得每个区间内都至少有一个点(不同区间内含的点可以是同一个). 贪心思想:先按bb从小到大进 ...

  2. *【UVA - 10382】Watering Grass(贪心,区间覆盖问题,思维)

    题干: 题目大意: 有一块草坪,长为l,宽为w,在它的水平中心线上有n个位置可以安装喷水装置,各个位置上的喷水装置的覆盖范围为以它们自己的半径ri为圆.求出最少需要的喷水装置个数,如果无论如何都不能覆 ...

  3. 【UVA - 10020 】Minimal coverage (贪心,区间覆盖问题)

    题干:(Uva题不给题干了) t组样例,每组首先给出一个M,然后给出一些线段(0 0结束),然后问怎么取能使得最少的线段覆盖区间[0, M]. Sample Input 2 1 -1 0 -5 -3 ...

  4. 【挑战程序设计竞赛】- 2.2贪心法(硬币最少、区间覆盖、字典序最小、标记最少、木板切割)

    四年前犯的错再做一遍还是会犯. 四年前不看presentation要求,四年后依然PE. 四年前忘记longlong,四年后还是会忘. 2.2 贪心法 核心思想:不断选取最优策略. 例题1-硬币:有1 ...

  5. 【算法笔记】:区间覆盖问题:贪心算法

    证明贪心算法的正确性: 下面证明: (1)最优子结构: 假设结果有n个区间,去掉最后一个区间及对应的点,则前n-1个区间仍然是覆盖所有点的所用的最少区间(最优解的子结构是子问题的最优解) 证明: cu ...

  6. 高效算法——E - 贪心-- 区间覆盖

    E - 贪心-- 区间覆盖 题目链接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=85904#problem/E 解题思路: 贪心思想, ...

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

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

  8. sdut 2074 区间覆盖问题(贪心)

    区间覆盖问题 Time Limit: 1000MS Memory limit: 65536K 题目描述 用i来表示x坐标轴上坐标为[i-1,i]的长度为1的区间,并给出n(1≤M≤200)个不同的整数 ...

  9. 贪心法——选择不相交区间

    贪心法--选择不相交区间 选择不相交区间.数轴上有nn个开区间(ai,bi)(a_i, b_i).选择尽量多个区间,使得这些区间两两没有公共点. 贪心思路:按b<script id=" ...

最新文章

  1. 在页面中隐藏数据库某信息并显示该信息对应的字典编码名称(后台ssh框架,前台extjs)
  2. Vue使用jsPdf将页面导出成pdf文件
  3. 采购杀毒软件,你说话能算数么?
  4. Java并发—基础操作
  5. ES6新特性之解构表达式
  6. QT显式调用VC开发的DLL
  7. uva 1153—— Keep the Customer Satisfied
  8. PID控制器改进笔记之一:改进PID控制器之参数动态调整
  9. 关于“Fluent UI”或Ribbon Design报道的补充说明
  10. 如何下载使用MSDN原版系统镜像
  11. C++ gbk与utf8互转
  12. 11个绝佳免费矢量素材下载网站,拿走不谢!
  13. spline本地运行的方法
  14. ZOHO:游刃于快时代的“慢公司”
  15. WINBUGS对随机波动率模型进行贝叶斯估计与比较
  16. 高端大气上档次的管理后台模板
  17. java中length,length()和size()各自含义
  18. Python:用tkinter制做一个音乐下载小软件
  19. halcon 缺陷检测 表面检测(分水岭)
  20. 可变长度操作码(扩展操作码)

热门文章

  1. 最全总结,GitHub Action自动化部署
  2. 1,2,3……,9组成3个三位数abc,def和ghi,每个数字恰好使用一次,要求abc:def:ghi=1:2:3.输出所有解。
  3. 【概念集锦】之 浅拷贝与深拷贝
  4. 通用职责分配软件原则之8-中介原则
  5. mitmproxy可谓神器乎?
  6. rabbitmq异步_在Node.js中使用RabbitMQ和Tortoise进行异步消息传递
  7. Leetcode-整数反转 C++
  8. python获取系统内存占用信息的实例方法
  9. Python爬虫开发:反爬虫措施以及爬虫编写注意事项
  10. Python高级——多线程(threading)