zoukankan      html  css  js  c++  java
  • 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

    inputoutput
    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
    ");
     97 
     98             continue;
     99         }
    100 
    101         printf("%d
    ",num);
    102 
    103         for(int i=0;i<num;i++)
    104         {
    105             printf("%d %d
    ",edge[ans[i]].l,edge[ans[i]].r);
    106         }
    107 
    108     }
    109 
    110     return 0;
    111 }
    View Code
     
     
     
  • 相关阅读:
    【xsy2506】 bipartite 并查集+线段树
    Linux K8s容器集群技术
    Linux 运维工作中的经典应用ansible(批量管理)Docker容器技术(环境的快速搭建)
    Linux Django项目部署
    Linux Django项目测试
    Linux 首先基本包安装(vim啊什么的),源,源优化,项目架构介绍, (LNMuWsgi)Django项目相关软件mysql,redies,python(相关模块)安装配置测试
    Linux centos系统安装后的基本配置,Linux命令
    Linux 虚拟机上安装linux系统 (ip:子网掩码,网关,dns,交换机,路由知识回顾)
    $ Django 调API的几种方式,django自定义错误响应
    $Django 路飞之显示视频,Redis存购物车数据,优惠卷生成表,优惠卷的一个领取表。(知识小回顾)
  • 原文地址:https://www.cnblogs.com/-maybe/p/4483609.html
Copyright © 2011-2022 走看看