https://codeforces.com/contest/1132/problem/C

 

采用逆向思维,要求最大的覆盖,就先求出总的覆盖,然后减去删除两个人贡献最少的人

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
vector<int> p[5002];
int con2[5002][5002],con1[5002];//一维数组:这个人的贡献,二维数组:这两个人共同的贡献 
int main(){
    int n,q;
    cin>>n>>q;
    int a,b;
    for(int i=1;i<=q;i++){
        cin>>a>>b;
        for(int j=a;j<=b;j++){
            p[j].push_back(i);//记录覆盖这个点的人 
        }
    }
    int total=0;
    for(int i=1;i<=n;i++){
        int m=p[i].size();
        if(m)
            total++;//算出覆盖的总数 
        if(m==1){//当前的点只有一个人覆盖的话,就算这个人的贡献 
            con1[p[i][0]]++;
        }
        else if(m==2){//有两个人覆盖的话,就算两个人的共同的贡献 
            con2[p[i][0]][p[i][1]]++;
            con2[p[i][1]][p[i][0]]++;
        }//如果有两个以上的话,就不算贡献了,因为及时删除两个人这个点还是被覆盖的 
    }
    int minn=INT_MAX;
    //遍历每两个点 
    for(int i=1;i<=q;i++){
        for(int j=i+1;j<=q;j++){
            minn=min(minn,con1[i]+con1[j]+con2[i][j]);//求出两个点的最小贡献 
        }
    }
    cout<<total-minn<<endl;
    return 0;
}