题目链接
题目思路
所有节点按照\(r\)排序,设\(dp[i]\)表示以\(i\)结尾的最长时间,然后每次转移,就是前\(i-1\)个的\(r\)值小于\(e[i].l\)的转移过来
由于\(r\)是单调上升的,利用二分+前缀最小值dp转移即可,发现这种线段题目基本都是这种思路
代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
#define fi first
#define se second
#define debug printf("aaaaaaaaaaa\n");
const int maxn=2e5+5,inf=0x3f3f3f3f,mod=1e9+7;
const ll INF=0x3f3f3f3f3f3f3f3f;
const double eps=1e-7;
int n;
int dp[maxn];
int prema[maxn];
struct node{
int l,r;
}e[maxn];
bool cmp(node a,node b){
return a.r<b.r;
}
int main(){
cin>>n;
for(int i=1;i<=n;i++){
cin>>e[i].l>>e[i].r;
}
sort(e+1,e+1+n,cmp);
for(int i=1;i<=n;i++){
int l=1,r=i,ans=0;
while(l<=r){
int mid=(l+r)/2;
if(e[mid].r<e[i].l){
ans=mid;
l=mid+1;
}else{
r=mid-1;
}
}
dp[i]=prema[ans]+e[i].r-e[i].l+1;
prema[i]=max(prema[i-1],dp[i]);
}
printf("%d\n",prema[n]);
return 0;
}