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