【pk赛】菜地
作者:互联网
题目
给你一块nxm的菜地,菜地的内容只由0和1组成
求最大的一块全为1的矩形子菜地
n,m<=1000
思路
首先可以预处理出每一行/每一块矩阵内1的个数
-
暴力枚举每一个矩阵的左上角、右下角
时间复杂度\(O(n^2m^2)\) -
枚举矩阵的起始两列位置,再用类似求最大子段和的思想dp
int ans=-1e9;
for(int l=1;l<=m;l++){
for(int r=l;r<=m;r++){
int tem=0,las=-1;
for(int i=1;i<=n;i++){
int cnt=pre[i][r]-pre[i][l-1];
if(cnt==r-l+1){
if(las==i-1){
tem+=cnt;
}
else tem=cnt;
las=i;
}
else{
las=-1;
tem=0;
}
if(tem>ans) ans=tem;
}
}
}
printf("%d\n",ans);
时间复杂度\(O(m^2n)\)
然而在这个数据范围下还是tle了
- 先预处理每个格子网上最多有多少个1,然后枚举每一个格子,求以它为基准的这一行的最大面积。
和单调栈例题——求矩阵最大面积题意一样
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 1005;
int n,m;
char a[1005][1005];
int h[N][N];
int r[N],l[N];
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
cin>>a[i][j];
}
}
for(int j=1;j<=m;j++){
for(int i=1;i<=n;i++){
if(a[i][j]=='0') h[i][j]=0;
else h[i][j]=h[i-1][j]+1;
}
}
int ans=0;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
l[j]=j;
r[j]=j;
}
h[i][0]=-1;
h[i][m+1]=-1;
for(int j=1;j<=m;j++){
while(h[i][j]<=h[i][l[j]-1]){
l[j]=l[l[j]-1];
}
}
for(int j=m;j>=1;j--){
while(h[i][j]<=h[i][r[j]+1]){
r[j]=r[r[j]+1];
}
}
for(int j=1;j<=m;j++){
ans=max(ans,(r[j]-l[j]+1)*h[i][j]);
}
}
cout<<ans<<endl;
return 0;
}
标签:菜地,int,矩阵,枚举,ans,pk,1005 来源: https://www.cnblogs.com/re0acm/p/16296751.html