链接:



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 0
-5 -3
2 5
0 0
No solution
1
-1 0
0 1
0 0
1
0 1

题意:

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

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

算法: 贪心


思路:

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

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


删除覆盖的:



最终可能状态:



code:

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std; const int maxn = 100000+10; struct Line{
int left,right;
}line[maxn], ans[maxn]; bool cmp(Line L1, Line L2) //从左到右排序,覆盖掉被其他线包含的线
{
if(L1.left != L2.left) return L1.left < L2.left;
else return L1.right >= L2.right;
} int main()
{
int m;
while(scanf("%d", &m) != EOF)
{
int left,right;
int n = 0;
for(;;)
{
scanf("%d%d", &left,&right);
if(left == 0 && right == 0) break;
line[++n].left = left;
line[n].right = right;
}
sort(line+1, line+n+1, cmp); int num = 1;
for(int i = 2; i <= n; i++) //覆盖过程
{
if(line[i].left > line[num].left && line[i].right > line[num].right)
line[++num] = line[i];
} n = num;
line[n+1].left = line[n+1].right = m+1; //边界处理
int cover = 0; //当前要求覆盖的点
int total = 0; //当前选中了的线
for(int i = 1; i <= n; i++)
{
if(line[i+1].left > cover && line[i].left <= cover)
{
ans[++total] = line[i];
cover = line[i].right;
if(cover >= m)
{
printf("%d\n", total);
for(int j = 1; j <= total; j++)
{
printf("%d %d\n", ans[j].left, ans[j].right);
}
return 0; //退出程序
}
}
}
printf("No solution\n");
}
return 0;
}

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. boost/config.hpp文件详解

    简要概述 今天突发奇想想看一下boost/config.hpp的内部实现,以及他有哪些功能. 这个头文件都有一个类似的结构,先包含一个头文件,假设为头文件1,然后包含这个头文 件中定义的宏.对于头文件 ...

  2. FormData上传文件同时附带其他参数

    前端js代码: function fileSubmit() { var formData = new FormData(); formData.append(].files[]); var type ...

  3. ES的关键端口

    ElasticSearch的集群可自发现,只要配置相同的集群名称,默认为组播发现机制,默认情况下: http 端口:9200 需要打开给调用 数据传输端口:9300 用于集群之间交换数据 组播端口(U ...

  4. JAVA Eclipse如何修改Android程序名称

    Values中修改strings.xml中的app_name即可   注意他是连接到AndroidManifest.xml文件的  

  5. cisco 为每个单独的人员设置不同的用户名和密码

    cisco 为每个单独的人员设置不同的用户名和密码 2010-12-15 17:00:16 分类: 系统运维 Router1#configure terminalEnter configuration ...

  6. linux路由服务

    本文介绍怎样使用linux创建一台简单的路由server. 主要包含几个參数的设置:ip_forward和rp_filter. 1.开启IP forwarding # 重新启动后失效 $ echo & ...

  7. jdk1.6 升级到 jdk1.7

    将 jdk1.6 升级到 jdk1.7 下载jdk-7u11-linux-x64.tar.gz   tar zxvf  jdk-7u11-linux-x64.tar.gz mkdir   /usr/l ...

  8. Smali语法:数据类型、方法和字段

    数据类型 dalvik字节码有两种类型,原始类型和引用类型.对象和数组是引用类型,其它都是原始类型. smali数据类型都是用一个字母表示,如果你熟悉Java的数据类型,你会发现表示smali数据类型 ...

  9. string转object-兼容低版本浏览器(eval实现)

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  10. Android开发之httpclient文件上传实现

    文件上传可能是一个比較耗时的操作,假设为上传操作带上进度提示则能够更好的提高用户体验,最后效果例如以下图: 项目源代码:http://download.csdn.net/detail/shinay/4 ...