文章目录
CF1132C Painting the Fence 题解
Painting the Fence
题目描述
You have a long fence which consists of n n n sections. Unfortunately, it is not painted, so you decided to hire q q q painters to paint it. i i i -th painter will paint all sections x x x such that l i ≤ x ≤ r i l_i \le x \le r_i li≤x≤ri .
Unfortunately, you are on a tight budget, so you may hire only q − 2 q - 2 q−2 painters. Obviously, only painters you hire will do their work.
You want to maximize the number of painted sections if you choose q − 2 q - 2 q−2 painters optimally. A section is considered painted if at least one painter paints it.
输入格式
The first line contains two integers n n n and q q q ( 3 ≤ n , q ≤ 5000 3 \le n, q \le 5000 3≤n,q≤5000 ) — the number of sections and the number of painters availible for hire, respectively.
Then $ q $ lines follow, each describing one of the painters: i i i -th line contains two integers l i l_i li and r i r_i ri ( 1 ≤ l i ≤ r i ≤ n 1 \le l_i \le r_i \le n 1≤li≤ri≤n ).
输出格式
Print one integer — maximum number of painted sections if you hire $ q - 2 $ painters.
题意描述
墙长为 n n n,有 q q q 个工人,每个工人固定粉刷一个区间,区间可能重叠,现在要去掉两个工人,求剩下 q − 2 q-2 q−2 个工人最多粉刷多少墙。( 3 ≤ n , q ≤ 5000 3 \le n,q \le 5000 3≤n,q≤5000) ( 1 ≤ l i ≤ r i ≤ n 1 \le l_i \le r_i \le n 1≤li≤ri≤n)
样例 #1
样例输入 #1
7 5
1 4
4 5
5 6
6 7
3 5
样例输出 #1
7
样例 #2
样例输入 #2
4 3
1 1
2 2
3 4
样例输出 #2
2
样例 #3
样例输入 #3
4 4
1 1
2 2
2 3
3 4
样例输出 #3
3
分析:
这是一道暴力枚举题。
不难从题目中发现,因为输入的是区间,所以可以用前缀和来存放每堵墙有几个人来涂。
又因为要去掉两个人,我们可以先枚举第一个被去掉的人。
于是问题就变成了去掉一个人的最优情况是多少。
再考虑第二个人的最优情况,得出最优解,即为答案。
代码:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const ll N=5010;
ll n,m,a[N],b[N],ans,p[N],p2[N],ct;
ll solve(ll x){
memset(p,0,sizeof(p));
memset(p2,0,sizeof(p2));
ct=LONG_LONG_MIN;
for(int i=0;i<m;i++)
if(i!=x) p[a[i]-1]++,p[b[i]]--;
for(int i=0;i<n;i++)
p[i]+=p[i-1];
for(int i=0;i<n;i++)
p2[i+1]=p2[i]+(p[i]==1);
for(int i=0;i<m;i++)
if(i!=x) ct=max(ct,-(p2[b[i]]-p2[a[i]-1]));
for(int i=0;i<n;i++) ct+=(p[i]>0);
return ct;
}
int main(){
ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
cin>>n>>m;
for(int i=0;i<m;i++) cin>>a[i]>>b[i];
for(int i=0;i<m;i++) ans=max(ans,solve(i));
cout<<ans;
return 0;
}
感谢大家~