题目连接:https://atcoder.jp/contests/agc040/tasks/agc040_b
大佬题解:https://blog.csdn.net/duanghaha/article/details/102892233
题意:有N个问题,每个问题可以由编号L~R之间的人完成,有两个集合S和T,将N个问题放入两个集合中,使得交集和最大
题解与证明
首先找到lmost,与rmin,当区间rmin与lmost在同一个集合中,此时答案为rmin-lmost+1+most_width(最大宽度)
当二者不再同一个集合中时,那么答案为 max((rmin-x+1)+(y-lmost+1))其中x为l[i],y为r[j]注意x与y不可以是同一个区间的左右边界。
现在已经确定了集合S中有lmost,所以,T中一定有rmin。。问题转换为一个数组,,两个参数,将这个数组划分为来年部分。使得两部分的和最大
ACcode
#include<bits/stdc++.h> using namespace std; const int INF=1e9+7; const int N=1E5+7; int l[N],r[N]; int arr[N]; struct stu{ int a,b; bool friend operator <(const stu &x,const stu &y){ return x.a>y.a; } }s[N]; int main() { int n; cin>>n; int lmax=0,rmin=INF,width=0; for(int i=1;i<=n;i++){ cin>>l[i]>>r[i]; if(l[i]>=lmax) lmax=l[i]; if(r[i]<=rmin) rmin=r[i]; width=max(width,r[i]-l[i]+1); } int sum=max(rmin-lmax+1,0)+width; for(int i=1;i<=n;i++){ s[i].a=max(0,rmin-l[i]+1); s[i].b=max(0,r[i]-lmax+1); } sort(s+1,s+1+n); arr[n]=s[n].b; for(int i=n-1;i>=1;i--) arr[i]=min(arr[i+1],s[i].b); int ans=0; for(int i=1;i<=n-1;i++) ans=max(ans,s[i].a+arr[i+1]); cout<<max(ans,sum)<<endl; return 0; }