作为一个资本家,农夫约翰希望通过购买更多的奶牛来扩大他的牛奶业务。
因此,他需要找地方建立一个新的牛棚。
约翰购买了一大块土地,这个土地可以看作是一个 R行(编号 1∼R1)C 列(编号 1∼C1)的方格矩阵。
不幸的是,他发现其中的部分方格区域已经被破坏了,因此他无法在整个 R×C 的土地上建立牛棚。
经调查,他发现共有 P 个方格内的土地遭到了破坏。
建立的牛棚必须是矩形的,并且内部不能包含被破坏的土地。
请你帮约翰计算,他能建造的最大的牛棚的面积是多少。
输入格式
第一行包含三个整数 R,C,P。
接下来 P 行,每行包含两个整数 r,c,表示第 r行第 c 列的方格区域内土地是被破坏的。
输出格式
输出牛棚的最大可能面积。
数据范围
1≤R,C≤3000,
0≤P≤30000,
1≤r≤R1,
1≤c≤C1;
输入样例:
3 4 2
1 3
2 1
输出样例:
6
解题思路:
题意是找到一个最大的矩形空间。
首先枚举每列的每个方格,代表了当前放个到不破坏方格的最大高度,用来表示矩形的高度。
再通过单调栈找到但当前高度高的放个,其前坐标就是放个的左起点,同理从后往前美剧第一个比当前方格高的其前一个坐标就是矩形的右起点。
确定了高度,左右起点,再通过枚举面积得到最大值。
参考代码:
#include <iostream>
#include <cstring>
#include <algorithm>using namespace std;
const int N = 3010;
int g[N][N],h[N][N];
int l[N],r[N];
int n,m,p;
int stk[N],top;int work(int h[])
{h[0] = h[m+1] = -1;top = 0;stk[++top] = 0;for(int i=1;i<=m;i++){while(h[stk[top]]>=h[i]) top--;l[i] = stk[top];stk[++top] = i;}top = 0;stk[++top] = m+1;for(int i=m;i;i--){while(h[stk[top]]>=h[i]) top--;r[i] = stk[top];stk[++top] = i;}int res = 0;for(int i=1;i<=m;i++)res = max(res,h[i]*(r[i]-l[i]-1));return res;
}int main()
{cin>>n>>m>>p;while(p--){int x,y;cin>>x>>y;g[x][y] = 1;}for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)if(!g[i][j])h[i][j] = h[i-1][j] + 1;int res = 0; for(int i=1;i<=n;i++)res = max(res,work(h[i]));cout<<res<<endl;return 0;
}