正题
考场上花了15分钟左右想的。
首先考虑r最小的一个区间,把它丢进第一个集合里面,其他区间按r排序,枚举一个区间丢到第二个集合里面,作为第二个集合里面r最小的区间,考虑剩下的区间应该怎么丢。
r<枚举的区间的r 的肯定丢到第一个集合里面,剩下的,它们的r显然都没有贡献,只在于最大的l是什么,把剩下的所有区间全部丢到第一个区间或者第二个区间计算贡献就可以了,对于相同的r,需要预处理出l的前后缀最小值。
#include<bits/stdc++.h>
using namespace std;
const int N=100010;
struct interval{
int l,r;
bool operator<(const interval q)const{
return r<q.r;
}
}s[N];
int n;
int maxl[N],lb[N],rb[N];
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d %d",&s[i].l,&s[i].r);
sort(s+1,s+1+n);
int firl=s[1].l;
for(int i=n;i>=1;i--) maxl[i]=max(maxl[i+1],s[i].l);
int now=2,ans=0;
while(now<=n){
int tmp=now;
while(now<=n && s[now].r==s[now+1].r) now++;
lb[tmp-1]=rb[now+1]=0;
for(int i=tmp;i<=now;i++) lb[i]=max(lb[i-1],s[i].l);
for(int i=now;i>=tmp;i--) rb[i]=max(rb[i+1],s[i].l);
int op=0;
for(int i=tmp;i<=now;i++){
op=max(lb[i-1],max(rb[i+1],maxl[now+1]));
ans=max(ans,max(s[1].r-min(max(firl,op),s[1].r+1)+1+s[i].r-s[i].l+1,s[1].r-firl+1+s[i].r-min(max(s[i].l,op),s[i].r+1)+1));
}
firl=min(max(firl,lb[now]),s[1].r+1);
now++;
}
printf("%d\n",ans);
}
区间分配算法解析
本文介绍了一种解决区间分配问题的算法思路,通过将区间按r值排序并分组,利用前后缀最小值预处理,计算两个集合中区间的最大贡献值。详细阐述了算法流程与实现细节。
853

被折叠的 条评论
为什么被折叠?



