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
题意:给出n,m。n指木板长度(1-n),m指m个工人。
接下来给m个区间,表示工人的粉刷范围,求m-2个工人最多粉刷多长的木板。
来自一个大佬博客:http://www.bubuko.com/infodetail-2977901.html
#include<cstdio>
#include<algorithm>
#include<stack>
#include<queue>
#include<map>
#include<set>
#include<cmath>
#include<vector>
#include<cstring>
#include<string>
#include<iostream>
#include<iomanip>
#define mset(a,b) memset(a,b,sizeof(a))
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
//const ll mod=1e9+7;
const int N=1000000;
const int inf=0x3f3f3f3f;
priority_queue<int,vector<int>,greater<int> >q;
int L[5005],dp[5005];
int main()
{
int n,m;
while(~scanf("%d%d",&n,&m))
{
for(int i=1;i<=n;i++)
{
L[i]=i+1;
dp[i]=0;
}
for(int i=1;i<=m;i++)
{
int l,r;
scanf("%d%d",&l,&r);
for(int j=l;j<=r;j++)
{
L[j]=min(L[j],l);
// L[]置为i+1是为了表示没有被画过的状态
}
}
for(int k=1;k<=m-2;k++)
{
for(int i=n;i>=1;i--)
{
dp[i]=max(dp[L[i]-1]+i-L[i]+1,dp[i]);
// L[i]~i的一段都被画了 长度为 i-L[i]+1
// 所以 dp[L[i]-1] 加上 L[i]到i被画的一段 更新dp[i]
}
for(int i=1;i<=n;i++)
{
dp[i]=max(dp[i],dp[i-1]);
// 短的段存在更优的方案 自然可以更新长的段
}
}
printf("%d\n",dp[n]);
}
return 0;
}