ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

【pk赛】菜地

2022-05-22 01:00:47  阅读:140  来源: 互联网

标签:菜地 int 矩阵 枚举 ans pk 1005


题目

给你一块nxm的菜地,菜地的内容只由0和1组成
求最大的一块全为1的矩形子菜地
n,m<=1000

思路

首先可以预处理出每一行/每一块矩阵内1的个数

  1. 暴力枚举每一个矩阵的左上角、右下角
    时间复杂度\(O(n^2m^2)\)

  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. 先预处理每个格子网上最多有多少个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

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有