链接:



D - Minimal Coverage

Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%I64d
& %I64u

Description

Given set of line segments [Li, Ri] with integer coordinates of their end points. Your task is to find the minimal subset of the given set which covers segment [0, M] completely (M is a positive integer).

Input

First line of the input contains an integer M (1 ≤ M ≤ 5000). Subsequent lines of input contain pairs of integers Li and Ri (abs(Li), abs(Ri) ≤ 50000). Each pair is placed on separate
line. Numbers in the pair are separated with space(s). List of pairs is ended with pair of zeroes. The list contains no more than 100000 pairs, including the pair of zeroes.

Output

Your program should print in the first line of output the power of minimal subset of segments which covers segment [0, M]. The list of segments of covering subset must follow. Format of the list must be the same as described
in input with exception that ending pair of zeroes should not be printed. Segments should be printed in increasing order of their left end point coordinate.
If there is no covering subset then print "No solution" to output.

Sample Input

input output
  1. 1
  2. -1 0
  3. -5 -3
  4. 2 5
  5. 0 0
  1. No solution
  1. 1
  2. -1 0
  3. 0 1
  4. 0 0
  1. 1
  2. 0 1

题意:

看的这里的翻译才懂的了= = 题目翻译

  1. 读入一个整数m(1<=m<=5000)。
  2. 接下来若干行,表示若干条线段。
  3. l[i]到r[i](最多100000条线段)。
  4. 到一行0 0为止。
  5. 求最少要用多少条线段可以覆盖区间[0,m]。
  6. 输出第一行一个数字,表示最少线段数。
  7. 接下来若干行表示选择的线段。按照顺序!!!注意:这里的按照顺序不是指线段输入的顺序而是每条线段的左右点的顺序
  8. 若无解则输出'No solution'

算法: 贪心


思路:

后来KB大神有说了一遍,然后和Orc讨论了下楼上的code才出来。

先按照输入的线段从左到右排序(即起点升序),排序时把被覆盖的线排再后面,程序中再忽略被覆盖的线
【不存在i,j使(l[i]<=l[j])&&(r[i]>=r[j]),即不存在某条线段被覆盖的情况】
为什么要删除被覆盖的线?因为如果选择了被覆盖的线,那么如果换成选择覆盖它的线结果不会更坏。
然后贪心
贪心的过程中先找出满足条件的覆盖 0 的线段,再以选择的这条线段的右端点的值为覆盖点,继续按照上面的步骤覆盖这个覆盖点,直到覆盖了 m 为止。
如何贪这样的满足的线段?
思路:找出所有的覆盖了这个点的线段,然后选择右端点最大的就可以了。
           如果一个个存或者比较的话很费时间和内存,那么开始的排序和删除被覆盖了的线就起到了作用,程序中稍微调整就可以满足情况。当所有的被覆盖了的线都删除了的时候,依次遍历所有的线,如果这条线覆盖了当前需要覆盖的点,而它的下一条线没有覆盖当前要覆盖的点,那么这就是要选择的线。也就是前面分析的覆盖了当前点的右端点最大的,因为重复的都删除了。


删除覆盖的:



最终可能状态:



code:

  1. #include<stdio.h>
  2. #include<string.h>
  3. #include<algorithm>
  4. using namespace std;
  5.  
  6. const int maxn = 100000+10;
  7.  
  8. struct Line{
  9. int left,right;
  10. }line[maxn], ans[maxn];
  11.  
  12. bool cmp(Line L1, Line L2) //从左到右排序,覆盖掉被其他线包含的线
  13. {
  14. if(L1.left != L2.left) return L1.left < L2.left;
  15. else return L1.right >= L2.right;
  16. }
  17.  
  18. int main()
  19. {
  20. int m;
  21. while(scanf("%d", &m) != EOF)
  22. {
  23. int left,right;
  24. int n = 0;
  25. for(;;)
  26. {
  27. scanf("%d%d", &left,&right);
  28. if(left == 0 && right == 0) break;
  29. line[++n].left = left;
  30. line[n].right = right;
  31. }
  32. sort(line+1, line+n+1, cmp);
  33.  
  34. int num = 1;
  35. for(int i = 2; i <= n; i++) //覆盖过程
  36. {
  37. if(line[i].left > line[num].left && line[i].right > line[num].right)
  38. line[++num] = line[i];
  39. }
  40.  
  41. n = num;
  42. line[n+1].left = line[n+1].right = m+1; //边界处理
  43. int cover = 0; //当前要求覆盖的点
  44. int total = 0; //当前选中了的线
  45. for(int i = 1; i <= n; i++)
  46. {
  47. if(line[i+1].left > cover && line[i].left <= cover)
  48. {
  49. ans[++total] = line[i];
  50. cover = line[i].right;
  51. if(cover >= m)
  52. {
  53. printf("%d\n", total);
  54. for(int j = 1; j <= total; j++)
  55. {
  56. printf("%d %d\n", ans[j].left, ans[j].right);
  57. }
  58. return 0; //退出程序
  59. }
  60. }
  61. }
  62. printf("No solution\n");
  63. }
  64. return 0;
  65. }

ural 1303 Minimal Coverage【贪心】的更多相关文章

  1. ural 1303 Minimal Coverage(贪心)

    链接: http://acm.timus.ru/problem.aspx?space=1&num=1303 按照贪心的思想,每次找到覆盖要求区间左端点时,右端点最大的线段,然后把要求覆盖的区间 ...

  2. 贪心 URAL 1303 Minimal Coverage

    题目传送门 /* 题意:最少需要多少条线段能覆盖[0, m]的长度 贪心:首先忽略被其他线段完全覆盖的线段,因为选取更长的更优 接着就是从p=0开始,以p点为标志,选取 (node[i].l < ...

  3. Ural 1303 Minimal Coverage(贪心)

    题目地址:Ural 1303 先按每一个线段的左端点排序,然后设置一个起点s.每次都从起点小于等于s的线段中找到一个右端点最大的. 并将该右端点作为新的起点s,然后继续找. 从左到右扫描一遍就可以. ...

  4. URAL 1303 Minimal Coverage

    URAL 1303 思路: dp+贪心,然后记录路径 mx[i]表示从i开始最大可以到的位置 sufmx[i]表从1-i的某个位置开始最大可以到达的位置 比普通的贪心效率要高很多 代码: #inclu ...

  5. URAL 1303. Minimal Coverage(DP)

    题目链接 又是输出路径...这题完全受上题影响,感觉两个题差不多..用了基本上一样的算法写了,这题比较纠结,就是卡内存啊...5000*5000的数组开不了..然后没办法,水了好几次MLE,看了一下虎 ...

  6. UVA 10020 Minimal coverage(贪心 + 区间覆盖问题)

     Minimal coverage  The Problem Given several segments of line (int the X axis) with coordinates [Li, ...

  7. uva.10020 Minimal coverage(贪心)

    10020 Given several segments of line (int the X axis) with coordinates [Li, Ri]. You are to choose t ...

  8. Minimal coverage (贪心,最小覆盖)

    题目大意:先确定一个M, 然后输入多组线段的左端和右端的端点坐标,然后让你求出来在所给的线段中能够 把[0, M] 区域完全覆盖完的最少需要的线段数,并输出这些线段的左右端点坐标. 思路分析: 线段区 ...

  9. uva 10020 Minimal coverage 【贪心】+【区间全然覆盖】

    Minimal coverage The Problem Given several segments of line (int the X axis) with coordinates [Li,Ri ...

随机推荐

  1. ES查询tags字段为空或null

    现需要查询出tags为 "" 或者为 null 的数据 { "query": { "bool": { "must": { ...

  2. Mybaits的特点及优点

    1.SQL语句和代码分离 便于统一管理和维护,不必再Java代码中调式SQL语句.但是当SQL语句出错时,控制台不会打印Log, 解决办法--引用log4j 2.用标签拼接SQL语句 用标签代替JAV ...

  3. 两种“新型”的javaweb后门(jspx和Java Logger)

    利用这个可以突破st2下   强制jsp跳转login.jsp 利用jspx解决jsp后缀被限制拿shell - Hack Blog | 黑客博客http://www.hackblog.cn/post ...

  4. 性能测试之Tomcat优化

    1.Tomcat最大连接数等配置   Tomcat的server.xml中Context元素的以下参数都是什么意思? <Connector port="8080"maxThr ...

  5. SQL语句练习手册--第四篇

    一.变量那点事儿 1.1 局部变量 (1)声明局部变量 DECLARE @变量名 数据类型 ) DECLARE @id int (2)为变量赋值 SET @变量名 =值 --set用于普通的赋值 SE ...

  6. c多线程学习

    http://www.ibm.com/developerworks/cn/linux/thread/posix_thread1/index.html http://blog.chinaunix.net ...

  7. CentOS 下Mysql数据库的安装与配置

    一.mysql简介 说到数据库,我们大多想到的是关系型数据库,比如mysql.oracle.sqlserver等等,这些数据库软件在windows上安装都非常 的方便,在Linux上如果要安装数据库, ...

  8. 简洁的BP及RBF神经网络代码

    BP神经网络 function [W,err]=BPTrain(data,label,hiddenlayers,nodes,type) %Train the bp artial nueral net ...

  9. 自动清理DataGuard备机日志

    >> from zhuhaiqing.info #!/usr/bin/bash #删除DataGuard备机归档日志备份 export ORACLE_HOME=/opt/oracle/pr ...

  10. C++ Primer(第五版)读书笔记 & 习题解答 --- Chapter 1

    Chapter 1.1 1. 每个C++程序都必须有且只能有一个main函数,main函数的返回类型必须是int.操作系统通过调用main函数来运行C++程序. 2. 一个函数的定义包含四部分:返回类 ...