线段覆盖5

codevs线段覆盖5

离散化+二分查找,按右端点排序,f[i]代表1~i的满足不覆盖的最大值,对于第i条线段,要么选,要么不选,所以方程为f[i]=max(f[i-1],f[find(i)]+e[i].v);find(i)是从右往左数第一个与i不相交的线段的下标,ansf[n];

 

#include<bits/stdc++.h>
using namespace std;
struct line
{
    long long l,r,v;
    bool operator <(const line&a)const
    {
        return r<a.r;
    }
}e[1000010];
long long n;
long long b[2000010];
long long f[1000010];
long long ans;
void in(long long &x)
{
    char c=getchar();x=0;
    while(c<'0'||c>'9')c=getchar();
    while(c<='9'&&c>='0')x=x*10+c-'0',c=getchar();
}

long long find(long long x)
{
    long long l=0,r=x-1,mid;
    while(l+1<r)
    {
        mid=(l+r)>>1;
        if(e[mid].r>e[x].l)
        r=mid;
        else
        l=mid;
    }
    if (e[r].r <= e[x].l) 
    return r;
    else 
    return l;
}

int main()
{
  in(n);
  for(long long i=1;i<=n;i++)
   {
       in(e[i].l),in(e[i].r),in(e[i].v);
       b[i]=e[i].l;
       b[i+n]=e[i].r;
    } 
  sort(b+1,b+2*n+1);    
  long long m=unique(b+1,b+2*n+1)-b-1;
  for(long long i=1;i<=n;i++)
    {
        e[i].l=lower_bound(b+1,b+m+1,e[i].l)-b;
        e[i].r=lower_bound(b+1,b+m+1,e[i].r)-b;
    }
    sort(e+1,e+n+1);
    for(long long i=1;i<=n;i++)
     {
         f[i]=max(f[i-1],f[find(i)]+e[i].v);
      } 
      cout<<f[n];
      return 0;
}

 

posted @ 2017-08-18 10:16  WeiAR  阅读(142)  评论(0编辑  收藏  举报