题解:P2701 [USACO5.3] 巨大的牛棚Big Barn
OldDriverTree · · 题解
题解区里好像没有单调栈的做法,这篇题解就讲解单调栈的做法。
多倍经验。
Solution
考虑先
枚举牛棚右上角点的
转化成的这个问题就和 这题 差不多。
当空地个数最小值不变时,区间长度显然是越长越好。
考虑求出每个位置左边第一个比他空地个数小的位置和右边第一个比他小的,就能求出区间长度。
单调栈即可,时间复杂度
Code
#include<bits/stdc++.h>
using namespace std;
const int N=1001;
int n,m,ans,a[N][N];
int L[N],R[N],s[N];
int main()
{
scanf("%d%d",&n,&m);
while (m--) {
int x,y;
scanf("%d%d",&x,&y);
a[x][y]=1;
}
for (int i=1;i<=n;i++)
for (int j=1;j<=n;j++)
a[i][j]=a[i][j]?0:a[i][j-1]+1;
for (int j=1;j<=n;j++)
{
for (int i=1,top=0;i<=n;i++) {
while (top&&a[s[top] ][j]>=a[i][j]) R[s[top] ]=i,top--;
L[i]=s[top],R[i]=n+1,s[++top]=i;
}
for (int i=1;i<=n;i++)
ans=max(ans,min(R[i]-L[i]-1,a[i][j]) );
}
printf("%d",ans);
return 0;
}