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