题意:
给一个n,一个q
n代表墙的宽度(米),q代表油漆工的人数
给q对数字,分别代表第i个油漆工刷墙的范围 l[i]~r[i]
只能选q-2个油漆工,问最多可以刷多少米的墙
解析:
用差分数组算出所有油漆工的刷墙效果,遍历每个油漆工(i),减少他刷的范围(-1),用前缀和计算他的范围内有多少个等于1
遍历每个油漆工(j),(i!=j,不能为同一个油漆工),比较从1变成0的个数
ac:
#include<bits/stdc++.h>
#define rep(i,l,r) for(int i=l;i<r;i++)
#define mem(gv) memset(gv,0,sizeof(gv))
#define ll long long
#define MAXN 10005
using namespace std;
int n,m,cnt;
int l[MAXN],r[MAXN],a[MAXN];
int d[MAXN],sum[MAXN];
int main()
{
memset(a,0,sizeof(a));
memset(l,0,sizeof(l));
memset(r,0,sizeof(r));
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++)
{
scanf("%d%d",&l[i],&r[i]);
a[l[i]]+=1;
a[r[i]+1]-=1;
}
for(int i=1;i<=n;i++)
a[i]+=a[i-1];
for(int i=1;i<=n;i++)//我们用d代替a
d[i]=a[i];
int ans=-1;
for(int j=1;j<=m;j++)
{
memset(sum,0,sizeof(sum));//别忘了每次都要重置
for(int i=l[j];i<=r[j];i++)
if(a[i]>=1)
d[i]--;
cnt=n;
for(int i=1;i<=n;i++)
{
if(d[i]==0)
cnt--;
if(d[i]==1)
sum[i]=1;
sum[i]+=sum[i-1];
}
int maxs=999999;
for(int i=1;i<=m;i++)
{
if(i==j) continue;
int g=sum[r[i]]-sum[l[i]-1];//变成0的数目
if(g<maxs)
maxs=g;
}
if(cnt-maxs>ans)
ans=cnt-maxs;
for(int i=l[j];i<=r[j];i++)//还原
d[i]=a[i];
}
printf("%d\n",ans);
return 0;
}