【Educational Codeforces Round 61(Div. 2)】Painting the Fence(思维)

题目链接

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个画家,给你每一个画家作画的区间[l_{i},r_{i}],让你挑选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);
}

猜你喜欢

转载自blog.csdn.net/qq_39826163/article/details/88571950