【专题】矩形和正方形的最大面积

news/2024/7/24 8:07:58 标签: 算法, 数据结构

一.矩形的最大面积——单调栈

(1)例题

P4147 玉蟾宫 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

(2)讲解(摘自题解)

问题转化:

  • n行m列土地,求最大矩形面积,我们把问题拆分成n个子问题来解决.

  • 对于每一行,依次记录每行向上一直是F土地的可延伸的最大距离,记为f(i,j).

    1. 当前元素(i,j)为F,则f(i,j)=f(i-1,j)+1.
    2. 当前元素(i,j)为R,则f(i,j)=0.
  • 我们记录这个数组有什么用呢?这就可以转化为单调栈维护的问题了.

具体思路:

  • 对于每一个子问题,我们维护一个单调递增的单调栈.我们定义一个结构体(其中记录的两个元素分别是当前行第j个矩形的f值,以及它在当前已加入栈中矩形高度的排名).

  • 我们考虑当前加入第k个矩形的情况.

    1. 当前矩形高度大于栈顶,直接加入即可,因为没有比它大的元素,那么他的排名为1.

    2. 当前矩形高度小于栈顶,则不断取出栈顶,直到栈为空或者栈顶矩形的高度比当前矩形小.在出栈过程中,我们累计被弹出的矩形的宽度之和,并且每弹出一个矩形,就用它的高度乘上累计的排名(是累计,因为在它入栈后还有比它大的元素入栈)来更新答案.

    3. 这样为什么是对的呢?这是因为:如果当前要加入矩形的f值(即当前矩形的高度比上一个小),那么该矩形想利用前面的矩形一起构成一个大矩形是,这块矩形的高度不可能超过该矩形自己的高度,则记录前面元素的高度就没有用处了.而宽度还有用处(因为当前矩形高度较小,与比它高的矩形的宽度总和相乘,在此矩形出栈时,要用它来更新答案).所以我们要记一个当前已加矩形的高度排名(无论是在栈里还是已经出栈).而又因为每个元素只被弹栈一次,所以不会有重复情况.

    4. 在所有矩形(m个)都考虑过后,我们再用还没有弹栈的元素再来个新一波答案,直到栈空

(3)AC

#include<bits/stdc++.h>
#define maxn 1005
using namespace std;
int n,m;
int ans,maxs;
struct node{
	int hign,length;
}sta[maxn];
int f[maxn][maxn]; //记录每行每列的高 
void work(int x){
	int top=1,len=0;
	maxs=0;
	sta[top].hign=f[x][1];
	sta[top].length=1;
	for(int i=2;i<=m;i++){
		len=0;
		//维持递增 
		while(sta[top].hign>=f[x][i] && top>0){
			len+=sta[top].length; //继承长度,毕竟高的可以,低的也必可以 
			maxs=max(maxs,sta[top--].hign*len);
		}
		sta[++top].hign=f[x][i];
		sta[top].length=len+1;
	}
	len=0;
	//同上while 
	while(top){
		len+=sta[top].length; 
		maxs=max(maxs,sta[top--].hign*len);
	}
	ans=max(ans,maxs);
}
int main(){
	scanf("%d%d",&n,&m);
	char c;
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			cin>>c;
			if(c=='F') f[i][j]=f[i-1][j]+1;
		}
	}
	//枚举每一行,解决子问题 
	for(int i=1;i<=n;i++) work(i);
	printf("%d",ans*3);
	return 0;
}

二.正方形的最大面积——dp

(1)例题

P1387 最大正方形 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

(2)讲解

就是一个简单的dp,dp状态转移方程式为:

dp[i][j]=min(min(dp[i-1][j],dp[i][j-1]),dp[i-1][j-1])+1;

(3)AC

#include<bits/stdc++.h>
#define maxn 101
using namespace std;
int n,m;
int a[maxn][maxn],dp[maxn][maxn];
int ans;
int main(){
	cin>>n>>m;
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)
			scanf("%d",&a[i][j]);
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			if(a[i][j]==1){
				dp[i][j]=min(min(dp[i-1][j],dp[i][j-1]),dp[i-1][j-1])+1;	
			}
			ans=max(ans,dp[i][j]);
		}
	} 
	cout<<ans;
	
}


http://www.niftyadmin.cn/n/5084750.html

相关文章

【广州华锐互动】智轨列车AR互动教学系统

智轨列车&#xff0c;也被称为路面电车或拖电车&#xff0c;是一种公共交通工具&#xff0c;它在城市的街头巷尾提供了一种有效、环保的出行方式。智轨列车的概念已经存在了很长时间&#xff0c;但是随着科技的发展&#xff0c;我们现在可以更好地理解和欣赏它。通过使用增强现…

安防视频监控平台EasyCVR集成到ios系统不能播放是什么原因?如何解决?

视频监控TSINGSEE青犀视频平台EasyCVR能在复杂的网络环境中&#xff0c;将分散的各类视频资源进行统一汇聚、整合、集中管理&#xff0c;在视频监控播放上&#xff0c;TSINGSEE青犀视频安防监控汇聚平台可支持1、4、9、16个画面窗口播放&#xff0c;可同时播放多路视频流&#…

让 Visual Studio 用上 ChatGPT

一、简介 Visual chatGPT Studio 是 Visual Studio 的一个免费扩展&#xff0c;它直接在 IDE 中添加了 chatGPT 功能。它允许用户以可以根据菜单功能的方式使用 chatGPT。 二、功能介绍 该扩展提供了一组使用 ChatGPT 命令&#xff0c;可以在编辑器中选择你需要处理的代码或…

【Vue】v-model修饰符

在Vue.js中&#xff0c;v-model 是一个指令&#xff0c;它用于实现双向数据绑定。它允许你在表单元素和组件中轻松绑定数据和用户输入&#xff0c;以便在用户输入数据时&#xff0c;数据会自动更新&#xff0c;反之亦然。v-model 修饰符是在 v-model 上的额外标记&#xff0c;用…

nginx windows安装部署,代理转发配置

一、安装 1、nginx官网下载 windows版本 nginx官网 下载后解压到本地 2、在nginx的配置文件是conf目录下的nginx.conf&#xff0c;默认配置的nginx监听的端口为80&#xff0c;如果本地电脑的80端口有被占用&#xff0c;如果本地80端口已经被使用则修改成其他端口。如下&…

Python【多分支选择结构1】

要求&#xff1a;输入赵本山的考试成绩&#xff0c;显示所获奖励 成绩100分&#xff0c;爸爸给他买辆车 成绩>90分&#xff0c;妈妈给他买MP4 90分>成绩>60分&#xff0c;妈妈给他买本参考书 成绩<60分&#xff0c;什么都不买 &#xff08;内容有修改无影响&#…

数学建模——确定性时间序列分析方法

目录 介绍 确定性时间序列分析方法 1、时间序列的常见趋势 &#xff08;1&#xff09;长期趋势 &#xff08;2&#xff09;季节变动 &#xff08;3&#xff09;循环变动 &#xff08;4&#xff09;不规则变动 常见的时间序列模型有以下几类 2、时间序列预测的具体方法 …

美国访问学者医疗保险要求与注意事项

在美国进行学术交流和研究的访问学者通常需要关注医疗保险的要求和注意事项。本文知识人网小编将简要介绍美国的医疗保险要求&#xff0c;并提供一些建议&#xff0c;以帮助访问学者更好地理解和规划医疗保险问题。 1.学校提供的医疗保险&#xff1a; 大多数美国的大学和研究机…