Timus 1303 Minimal Coverage DP或贪心

            1303. Minimal Coverage

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 (−50000 ≤ Li < Ri ≤ 50000). Each pair of coordinates is placed on separate line. Numbers in the pair are separated with space. Last line of input data contains a pair of zeroes. The set contains at least one and at most 99999 segments.

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.

Samples

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

输入m

给出一些线段,

问最少选择多少条可以覆盖区间[0,m],

输出条数

然后按左端点小到大输出这些线段。

维护当前的最右端点(刚开始是0)
然后找左端点小于这个点的且右端点最大的线段
更新最右端点

主要看注释

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<algorithm>
  4
  5 using namespace std;
  6
  7 const int maxn=100000+4;
  8
  9 struct Edge
 10 {
 11     int l,r;
 12 }edge[maxn];
 13
 14 bool cmp(Edge a,Edge b)
 15 {
 16     if(a.l==b.l)
 17         return a.r<b.r;
 18     return a.l<b.l;
 19 }
 20
 21 int ans[maxn];
 22
 23 int main()
 24 {
 25     int m;
 26
 27     while(scanf("%d",&m)!=EOF)
 28     {
 29
 30         int tot=1;
 31
 32         scanf("%d%d",&edge[tot].l,&edge[tot].r);
 33
 34         if(edge[tot].l==0&&edge[tot].r==0)
 35             break;
 36
 37         while(edge[tot].l||edge[tot].r)
 38         {
 39             tot++;
 40             scanf("%d%d",&edge[tot].l,&edge[tot].r);
 41         }
 42
 43         sort(edge+1,edge+tot,cmp);
 44
 45         int num=0;
 46         int cur=0;
 47         int cnt=0;
 48         edge[0].l=edge[0].r=-55555;
 49
 50         bool flag=true;
 51
 52         while(true)
 53         {
 54             if(cur>=m)
 55             {
 56                 break;
 57             }
 58
 59
 60             //这里犯了一个极大的错误
 61             //我刚开始的代码是这样的:
 62             //while(cnt+1<tot&&edge[cnt+1].l<=cur&&edge[cnt+1].r>edge[cnt].r)
 63             //    cnt++;
 64             //我们是要找出满足左端点在cur左边的所有线段中,
 65             //的右端点最远的点
 66             //所以要用变量right表示当前最远的,
 67             //然后跟right比较
 68             //而不是跟前面的线段比较。
 69
 70
 71             int right=cur;
 72             for(int i=cnt;i+1<tot;i++)
 73             {
 74                 if(edge[i+1].l<=cur&&edge[i+1].r>right)
 75                 {
 76                     cnt=i+1;
 77                     right=edge[cnt].r;
 78                 }
 79             }
 80
 81             if(edge[cnt].r<=cur)
 82             {
 83                 flag=false;
 84                 break;
 85             }
 86
 87             else
 88             {
 89                 ans[num++]=cnt;
 90                 cur=edge[cnt].r;
 91             }
 92         }
 93
 94         if(!flag)
 95         {
 96             printf("No solution\n");
 97
 98             continue;
 99         }
100
101         printf("%d\n",num);
102
103         for(int i=0;i<num;i++)
104         {
105             printf("%d %d\n",edge[ans[i]].l,edge[ans[i]].r);
106         }
107
108     }
109
110     return 0;
111 }

时间: 2024-08-01 21:47:41

Timus 1303 Minimal Coverage DP或贪心的相关文章

贪心 URAL 1303 Minimal Coverage

题目传送门 1 /* 2 题意:最少需要多少条线段能覆盖[0, m]的长度 3 贪心:首先忽略被其他线段完全覆盖的线段,因为选取更长的更优 4 接着就是从p=0开始,以p点为标志,选取 (node[i].l <= p && p < node[i+1].l) 5 详细解释:http://www.cnblogs.com/freezhan/p/3219046.html 6 */ 7 #include <cstdio> 8 #include <iostream>

Ural 1303 Minimal Coverage(贪心)

题目地址:Ural 1303 先按每个线段的左端点排序,然后设置一个起点s,每次都从起点小于等于s的线段中找到一个右端点最大的.并将该右端点作为新的起点s,然后继续找.从左到右扫描一遍即可. 代码如下: #include <iostream> #include <cstdio> #include <string> #include <cstring> #include <stdlib.h> #include <math.h> #inc

uva 10020 Minimal coverage 【贪心】+【区间完全覆盖】

Minimal coverage The Problem Given several segments of line (int the X axis) with coordinates [Li,Ri]. You are to choose the minimal amount of them, such they would completely cover the segment [0,M]. The Input The first line is the number of test ca

UVA Minimal coverage (贪心)

Description  Minimal coverage  The Problem Given several segments of line (int the X axis) with coordinates [Li,Ri]. You are to choose the minimal amount of them, such they would completely cover the segment [0,M]. The Input The first line is the num

Timus OJ 1057 数位dp

http://acm.timus.ru/problem.aspx?space=1&num=1057 1057. Amount of Degrees Time limit: 1.0 second Memory limit: 64 MB Create a code to determine the amount of integers, lying in the set [X;Y] and being a sum of exactlyK different integer degrees of B.

【区间覆盖问题】uva 10020 - Minimal coverage

可以说是区间覆盖问题的例题... Note: 区间包含+排序扫描: 要求覆盖区间[s, t]; 1.把各区间按照Left从小到大排序,如果区间1的起点大于s,则无解(因为其他区间的左起点更大):否则选择起点在s的最长区间; 2.选择区间[li, ri]后,新的起点应更新为ri,并且忽略所有区间在ri之前的部分:  Minimal coverage  The Problem Given several segments of line (int the X axis) with coordinat

uva10020 - Minimal coverage(区间覆盖)

题目:uva10020 - Minimal coverage(区间覆盖) 题目大意:给出一些线段,然后问怎样取能使得最少的线段覆盖区间[0, M]. 解题思路:先预处理掉那些和区间[0,M]不沾边的线段. 将线段按照起点小的排序. 接着遍历这些线段.首先先判断起点最小的点是否<=0,如果不满足这个说明它不能覆盖区间. 然后每次都小于等于当前覆盖的起点的最长线段,之后要将起点更新成这个最长线段的终点.然后接着判断下一条线段.如果更新了起点发现依然找不到满足条件的线段,说明不能覆盖. 最后还要看一下

HDU 5135 Little Zu Chongzhi&#39;s Triangles(状压dp或者贪心)

题目大意:给你n个线段让你任意组成三角形,求组出来的三角形的面积的和最大为多少. 解题思路:首先你得知道海伦公式:S = sqrt(p*(p-a)*(p-b)*(p-c)), p = (a+b+c)/2. 思路一:贪心,按照边的长度进行排序,从大到小判断如果可以构成三角形,就让他构成三角形,这样组成的三角形的面积和一定是最大的. 思路二:状压dp,先暴力求出来所有可以组成的三角形对应的状态和面积,然后dp求解,状态转移公式是:dp[i|(f[j].xnum)] = max(dp[i|(f[j].

数位dp,贪心,线性dp复习总结

通过一个月的奋(hua)斗(shui),我顺利的躺在了苏俄战场上. 这个月主要是 你的目标 数位dp 玄学 贪心 诡异 线性dp 提刀 ... 数位dp主要是有两种方法 一种是先把表刷完,再乱搞: 还有一种直接乱搞. 总而言之 都是乱搞过得. 贪心贪的巨诡异,感觉做了一些好题,贪心方法可能略微拓展了一下,贪心思想进一步加深. 总之,多玩贪吃蛇......... 线性dp,水题一大片,打消我的做题欲望,只要有什么地方写卡了就在那个地方加一维..... 没错就是这样,因为出题人太水了喜欢这样出..因