• Week3 作业 C


    题目描述:

    数轴上有 n (1<=n<=25000)个闭区间 [ai, bi],选择尽量少的区间覆盖一条指定线段 [1, t]( 1<=t<=1,000,000)。
    覆盖整点,即(1,2)+(3,4)可以覆盖(1,4)。
    不可能办到输出-1

    思路:

    按顺序贪最长有效长度;

    直观上来说,选一个区间,一定要让其最大有效长度最大,那么如何判断一个区间的有效长度?假设已经选了i个区间,当选择第i+1区间时,要看第i+1个区间里有多少长度没有被覆盖,这也就是第i+1个区间的有效长度,如果选第i+1个区间时,从左端点到右端点搜索,则时间复杂度是O(n^n);为了在选择时,不对后序的选择产生影响,我们对左端点进行排序,这样就可以顺序的用O(n)的时间遍历所有区间

    正确性证明:

    假设已经选了k个区间,其覆盖范围是从L到R(假设L>1),则接下来需要选择的区间一定有左端点在[1,L]之间的,假设我们又选择了一个区间,其左端点是LL(1<LL<L),则接下来仍然要选择左端点在[1,LL]之间的区间,依次类推,则一定要选择开头是1的区间;而如果按顺序从1开始选择区间,因为每次选的是有效长度最大的,所以第一个选的区间不会比最优解中从1开始的那个区间的覆盖长度短;假设选了[1,RR],则把RR+1相当于是1,继续重复上述推证,可得到这种方法的解不会比最优解差。

    总结:

    贪心往往和排序相联系

    代码:

     1 //贪最长有效长度,按顺序贪,假设已经选了[1,K],下一步一定要选一个起点在[2,K+1]之内的区间,每个区间都有一个有效长度,max_就是这些区间的最长有效长度
     2 #include <cstdio>
     3 #include <iostream>
     4 #include <algorithm>
     5 using namespace std;
     6 struct sec
     7 {
     8     int l,r,len;  //区间的起点,终点和长度 
     9     bool operator< (const sec &x) const
    10     {
    11         if(l!=x.l) return l<x.l;    //左端点升序,长度降序 
    12         else if(len!=x.len) return len>x.len;
    13     }
    14 }a[100005]; 
    15 int main()
    16 {
    17     int n,t; cin>>n>>t;
    18     for(int i=1;i<=n;i++)
    19         scanf("%d %d",&a[i].l,&a[i].r),
    20         a[i].len=a[i].r-a[i].l;
    21     sort(a+1,a+n+1);
    22     int end=0,oldEnd=0,i=1,ans=0;
    23     while( end<t )
    24     {
    25         int max_=0; 
    26         i--;
    27         while(1)
    28         {
    29             i++;
    30             if( a[i].l<=end+1 )  //计算有效长度
    31             {
    32                 if( a[i].r-end> max_) max_=a[i].r-end;
    33             }         
    34             else break;   //当break时,i加到了下次的位置,所以上方i--,并设i的初始值是1 
    35         }
    36         if(max_==0)
    37         {
    38             cout<<-1<<endl;
    39             return 0;
    40         }
    41         end=end+max_;
    42         ans++;
    43     }
    44     cout<<ans<<endl;
    45 } 
  • 相关阅读:
    C语言II作业01
    C语言寒假大作战04
    C语言寒假大作战03
    C语言寒假大作战02
    C语言寒假大作战01
    C语言I博客作业12—学期总结
    第一次作业
    C语言I博客作业02
    C语言I博客作业11
    C语言||作业01
  • 原文地址:https://www.cnblogs.com/qingoba/p/12535226.html
Copyright © 2020-2023  润新知