C. Painting the Fence
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output
You have a long fence which consists of nn sections. Unfortunately, it is not painted, so you decided to hire qq painters to paint it. ii-th painter will paint all sections xx such that li≤x≤rili≤x≤ri.
Unfortunately, you are on a tight budget, so you may hire only q−2q−2 painters. Obviously, only painters you hire will do their work.
You want to maximize the number of painted sections if you choose q−2q−2 painters optimally. A section is considered painted if at least one painter paints it.
Input
The first line contains two integers nn and qq (3≤n,q≤50003≤n,q≤5000) — the number of sections and the number of painters availible for hire, respectively.
Then qq lines follow, each describing one of the painters: ii-th line contains two integers lili and riri (1≤li≤ri≤n1≤li≤ri≤n).
Output
Print one integer — maximum number of painted sections if you hire q−2q−2 painters.
Examples
input
Copy
7 5 1 4 4 5 5 6 6 7 3 5
output
Copy
7
input
Copy
4 3 1 1 2 2 3 4
output
Copy
2
input
Copy
4 4 1 1 2 2 2 3 3 4
output
Copy
3
【题意】
有k个画家,给你每一个画家作画的区间,让你挑选k-2个画家,使绘画的部分尽可能大。
【解题思路】
首先计算出每个点可以由哪些画家完成,然后需要用到逆向思维,因为最终需要挑出q-2个画家使绘画的部分尽可能大,那么只需将能够画的所有点计算出来-2个画家完成的最小贡献即可。因为如果一个点被3个及以上的画家覆盖的话,那么这个点就没有必要记录,因为就算删去这两个画家,这个点最终还是可以被完成的。所以只需要记录被1个或被两个画家覆盖的点的个数。最后遍历一下删哪两个画家即可。
【代码】
#include<bits/stdc++.h>
using namespace std;
const int INF=0x3f3f3f3f;
const int maxn=5005;
vector<int>v[maxn];
int a[maxn],b[maxn][maxn];
int main()
{
int n,q,ans=INF,sum=0,l,r;
scanf("%d%d",&n,&q);
for(int i=1;i<=q;i++)
{
scanf("%d%d",&l,&r);
for(int j=l;j<=r;j++)
v[j].push_back(i);
}
for(int i=1;i<=n;i++)
{
int m=v[i].size();
if(m!=0)sum++;
if(m==1)a[v[i][0]]++;
else if(m==2)b[v[i][0]][v[i][1]]++;
}
for(int i=1;i<=q;i++)
{
for(int j=i+1;j<=q;j++)
ans=min(ans,a[i]+a[j]+b[i][j]);
}
printf("%d\n",sum-ans);
}