YunYan

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

题目连接: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;
 } 

 

posted on 2019-11-08 13:48  Target--fly  阅读(139)  评论(0编辑  收藏  举报