《深入浅出进阶篇》洛谷P4147 玉蟾宫——悬线法dp

news2024/12/23 13:41:19

上链接:P4147 玉蟾宫 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)icon-default.png?t=N7T8https://www.luogu.com.cn/problem/P4147

上题干:

有一个NxM的矩阵,每个格子里写着R或者F。R代表障碍格子,F代表无障碍格子请找出其中的一个子矩阵,其元素均为‘F’,并且面积最大,输出它的面积*3的值

求最大子矩阵我们一般用到一个方法叫——悬线法;

下面来介绍悬线法:

我们找任意找一个非障碍格子作为底边的一个格子,从该点出发,引出3条直线,左直线,右直线,上直线。

我们从这个点出发,向左一直延伸直到遇到障碍格,向右一直延伸一直延长到障碍格子,同理,向上也是。

第一步:

设置四个数组:

棋盘:char a[N][N];

左悬线数组:表示每个格子能向左延伸到的最远距离, int l[N][N];

右悬线 :表示每个格子能向右延伸到的最远距离,int r[N][N] ;

上悬线:表示每个格子能向上延伸到的最远距离 int h[N][N];

第二步:

求左悬线:

思路:

我们先将每个格子的向左能延伸到的最远距离初始化为该格子本身的列数,也就是它一开始只能延伸到它本身。

以第一行为例:

然后循环每一列,从最左边开始,当a[i][j]为空地,并且a[i][j-1]为空地的时候,该格子的左悬线能延伸到的位置就是左边一格能延伸到的位置。

所以有此代码:

	
for (int i = 1; i <= n; i++)
	for (int j = 1; j <= m; j++)
		if (a[i][j] == 'F' and a[i][j - 1] == 'F')l[i][j] = l[i][j - 1];

这样就可以求出所有格子的左悬线了。

同理

求右悬线:

思路:

我们先将每个格子的向右能延伸到的最远距离初始化为该格子本身的列数,也就是它一开始只能延伸到它本身

循环每一列,从最右边开始,当a[i][j]为空地,并且a[i][j+1]为空地的时候,该格子的右悬线能延伸到的位置就是右边一格能延伸到的位置。

 

for (int i = 1; i <= n; i++)
	for (int j = m; j >= 1; j--)
		if (a[i][j] == 'F' and a[i][j + 1] == 'F')r[i][j] = r[i][j + 1];

求上悬线:

思路:

我们先将每个格子的向上能延伸到的最远距离初始化为该格子本身的高度,即为1,也就是它一开始只能延伸到它本身

循环每一列,从任意一遍开始都行,我们以从左边开始为例子,当a[i][j]为空地,并且a[i-1][j]为空地的时候,该格子的上悬线能延伸到的位置就是上边一格能延伸到的位置。

for (int i = 1; i <= n; i++)
	for (int j = 1; j <= m; j++)
		if (a[i][j] == 'F' and a[i - 1][j] == 'F')h[i][j] = h[i - 1][j] + 1;

将这三个代码整合起来就是这样的:

for (int i = 1; i <= n; i++)
{
	for (int j = 1; j <= m; j++)
		if (a[i][j] == 'F' and a[i][j - 1] == 'F')l[i][j] = l[i][j - 1];
	for (int j = m; j >= 1; j--)
		if (a[i][j] == 'F' and a[i][j + 1] == 'F')r[i][j] = r[i][j + 1];
	for (int j = 1; j <= m; j++)
		if (a[i][j] == 'F' and a[i - 1][j] == 'F')h[i][j] = h[i - 1][j] + 1;
}

第三步:

求每个格子以上悬线为高的矩形面积

到这里还没有结束,不要傻乎乎的就用每一个格子的三个悬线开始计算面积了。

我们应该可以注意到,有这样一种情况:

如果直接拿右悬线-左悬线 乘以高的话,求出来的面积 是绿色矩形的面积,然而实际上我们希望求的是在上悬线尽可能高的情况下的矩形面积(目的是使得枚举不重不漏)。

所以我们还需要修改一个条件,该格的左悬线应该为 (该格,和上面一格)的左悬线之间长度小的那一根。

由于l[i][j]代表的是该格向左能延伸到的最远的坐标(离得越远,坐标越小),所以我们需要让l[i][j]尽可能大,

同理,我们要让r[i][j]尽可能的小。

那么则有:

for (int i = 1; i <= n; i++)
	for (int j = 1; j <= m; j++) 
		if (a[i][j] == 'F' and a[i - 1][j] == 'F') {
			r[i][j] = min(r[i][j], r[i - 1][j]);
			l[i][j] = max(l[i][j], l[i - 1][j]);
          }

到这里就基本结束了。

第四步:

最后我们只需要打擂台,不断求出每个格子三悬线组成的面积的最大值就可以了。

也就是: 

for (int i = 1; i <= n; i++)	
	if (a[i][j] == 'F')
		ans = max(ans, h[i][j] * (r[i][j] - l[i][j] + 1));

总的来看,这道题一共有四个步骤,设三条悬线,求三条悬线,求以上悬线为高的矩形面积,打擂台求最大值。

上代码:


const int N = 1010;
int n, m, ans;
char a[N][N];
int h[N][N], l[N][N], r[N][N];
int main()
{
	ans = 0;
	cin >> n >> m;
	for (int i = 1; i <= n; i++)
		for (int j = 1; j <= m; j++)
		{
			cin >> a[i][j];
			h[i][j] = 1, r[i][j] = l[i][j] = j;//初始化h,r,l
		}
	for (int i = 1; i <= n; i++)
	{
		for (int j = 1; j <= m; j++)
			if (a[i][j] == 'F' and a[i][j - 1] == 'F')l[i][j] = l[i][j - 1];
		for (int j = m; j >= 1; j--)
			if (a[i][j] == 'F' and a[i][j + 1] == 'F')r[i][j] = r[i][j + 1];
		for (int j = 1; j <= m; j++)
			if (a[i][j] == 'F' and a[i - 1][j] == 'F')h[i][j] = h[i - 1][j] + 1;
	}
	for (int i = 1; i <= n; i++)
	{
		for (int j = 1; j <= m; j++) {
			if (a[i][j] == 'F' and a[i - 1][j] == 'F') {
				r[i][j] = min(r[i][j], r[i - 1][j]);
				l[i][j] = max(l[i][j], l[i - 1][j]);
			}
			if (a[i][j] == 'F')
				ans = max(ans, h[i][j] * (r[i][j] - l[i][j] + 1));
		}
	}
	cout << 3 * ans;

}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1205870.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

做一个Sprngboot文件上传-阿里云

概述 这个模块是用来上传头像以及文章封面的&#xff0c;图片的值是一个地址字符串&#xff0c;一般存放在本地或阿里云服务中 1、本地文件上传 我们将文件保存在一个本地的文件夹下&#xff0c;由于可能两个人上传不同图片但是却同名的图片&#xff0c;那么就会一个人的图片就…

JavaEE——网络原理(网络层 IP协议与数据链路层)

文章目录 一、详细解释 IP协议二、解释 TCP 和 IP 之间的联系和区别。三、IP协议——地址管理四、数据链路层 一、详细解释 IP协议 注&#xff1a;在这里我向大家描述的 IP协议是 IPv4。 如上图所示&#xff0c;这就是 IP 协议头的格式&#xff0c;下面我会分别解释他们其中每…

【C++笔记】AVL树的模拟实现

【C笔记】AVL树的模拟实现 一、AVL树的概念二、AVL树的模拟实现2.1、定义节点2.2、插入2.3、旋转2.3.1、左单旋2.3.2、右单旋2.3.3、左右双旋2.3.4、右左双旋2.3.5、插入接口的整体代码实现 三、验证AVL树3.1、验证 一、AVL树的概念 二叉搜索树虽然在一般情况下可以提高查找的…

如何使用`open-uri`模块

首先&#xff0c;我们需要使用open-uri模块来打开网页&#xff0c;并使用Nokogiri模块来解析网页内容。然后&#xff0c;我们可以使用Nokogiri的css方法来选择我们想要的元素&#xff0c;例如标题&#xff0c;作者&#xff0c;内容等。最后&#xff0c;我们可以使用open-uri模块…

多语言TTS:Multilingual speech synthesis

文章目录 [Learning to Speak Fluently in a Foreign Language:Multilingual Speech Synthesis and Cross-Language Voice Cloning](https://arxiv.org/abs/1907.04448)[2019interspeech][google][Improving Cross-lingual Speech Synthesis with Triplet Training Scheme](htt…

3DMAX建模基础教程:捕捉功能

在3DMAX中&#xff0c;捕捉功能是一项极其重要的技术&#xff0c;它能帮助我们在创建三维模型时更加精确和高效。本教程将详细介绍3DMAX中的捕捉功能及其应用。 1. 捕捉简介 3DMAX中的捕捉功能是指将物体固定在三维空间中的特定位置&#xff0c;以便进行精确的建模操作。这种…

0基础学习VR全景平台篇第120篇:极坐标处理接缝 - PS教程

上课&#xff01;全体起立~ 大家好&#xff0c;欢迎观看蛙色官方系列全景摄影课程&#xff01; 紧跟上节课&#xff0c;我们已经学会了怎么利用PS蒙版工具来对航拍全景图补天。但是在后续工作学习中&#xff0c;我们会遇到天空这部分存在部分接缝的问题&#xff0c;如图&…

算法通关村第八关-黄金挑战

大家好我是苏麟 ...... 路径总和2 描述 : 给你二叉树的根节点 root 和一个整数目标和 targetSum &#xff0c;找出所有 从根节点到叶子节点 路径总和等于给定目标和的路径。 叶子节点 是指没有子节点的节点。 题目 : LeetCode 113.路径总和2 113. 路径总和 II 分析 : 这…

为什么UI自动化难做?—— 关于Selenium UI自动化的思考

在快速迭代的产品、团队中&#xff0c;UI自动化通常是一件看似美好&#xff0c;实际“鸡肋”&#xff08;甚至绝大部分连鸡肋都算不上&#xff09;的工具。原因不外乎以下几点&#xff1a; 1 效果有限 通常只是听说过&#xff0c;就想去搞UI自动化的团队&#xff0c;心里都认…

数据跨领域应用实例—车辆通行大数据应用场景(二)

2023年10月25日&#xff0c;国家数据局正式揭牌。标志着我国数据基础制度正在不断完善&#xff0c;数据资源使用水平稳步提升&#xff0c;数据要素市场将进入发展快车道。当前&#xff0c;数字经济已成为我国经济高质量发展的新动能&#xff0c;国家数据局的成立&#xff0c;在…

Python高级语法----Python类型注解与类型检查

文章目录 一、类型注解基础二、使用 `mypy` 进行类型检查三、类型注解的最佳实践结论在当今的软件开发实践中,类型注解和类型检查在提高代码的可读性和健壮性方面发挥着至关重要的作用。尤其在 Python 这种动态类型语言中,通过类型注解和类型检查工具,如 mypy,可以显著提升…

python爬虫代理ip关于设置proxies的问题

目录 前言 一、什么是代理IP? 二、为什么需要设置代理IP? 三、如何设置代理IP? 四、完整代码 总结 前言 在进行Python爬虫开发时&#xff0c;经常会遇到被封IP或者频繁访问同一网站被限制访问等问题&#xff0c;这时&#xff0c;使用代理IP就可以避免这些问题&#x…

微软允许OEM对Win10不提供关闭Secure Boot

用户可能将无法在Windows 10电脑上安装其它操作系统了&#xff0c;微软不再要求OEM在UEFI 中提供的“关闭 Secure Boot”的选项。 微软最早是在Designed for Windows 8认证时要求OEM的产品必须支持UEFI Secure Boot。Secure Boot 被设计用来防止恶意程序悄悄潜入到引导进程。问…

高版本模拟器安装burp证书

一、下载burp证书&#xff0c;安装openssl http://burp自己找官网安装opensslWin32/Win64 OpenSSL Installer for Windows - Shining Light Productions (slproweb.com)二、查看模拟器端口并连接 adb devices openssl x509 -inform der -in cacert.der -out burp.pem openssl…

一分多行列转换

问题描述&#xff1a; 将以下表方式存放的数据&#xff1a; 转换成如下方式存放&#xff1a; 1、 建表语句及插入测试数据 --建表语句 create table INFC_C_GUARANTOR_NISJ (CUST_NO VARCHAR2(30),BAIL_ACCT_NO VARCHAR2(2000) ); create table INFC_C_GUARANTOR_NISJ_N…

重复性工作自动化解决方案——影刀

以前&#xff0c;影刀是一个邂逅的初见小工具&#xff0c;新奇在里头&#xff0c;踌躇在外头&#xff1b; 现在&#xff0c;影刀是一个稳定的职场贾维斯&#xff0c;高效在里头&#xff0c;悠闲在外头&#xff1b; 以后&#xff0c;影刀是一个潜力的知己老司机&#xff0c;有序…

ROS 通信机制

ROS是一个分布式框架&#xff0c;为用户提供多节点&#xff08;进程&#xff09;之间的通信服务&#xff0c;所有软件和功能都建立在这种分布式通信机制上&#xff0c;ROS的通信机制是最底层也是最核心的技术。 一、话题通信机制 话题在 ROS 中使用最为频繁&#xff0c;其通信…

Python实现WOA智能鲸鱼优化算法优化循环神经网络分类模型(LSTM分类算法)项目实战

说明&#xff1a;这是一个机器学习实战项目&#xff08;附带数据代码文档视频讲解&#xff09;&#xff0c;如需数据代码文档视频讲解可以直接到文章最后获取。 1.项目背景 鲸鱼优化算法 (whale optimization algorithm,WOA)是 2016 年由澳大利亚格里菲斯大学的Mirjalili 等提…

【VECTOR】:CAN OE Alyzer使用

CAN OE Alyzer使用 工程搭建新建工程DBC文件导入插入IG模块Trace查看录制Logger回放Trace 实际应用将需要回放报文的导出需要报文添加导出的报文&#xff0c;回放添加诊断CDD 工程搭建 新建工程 配置硬件1&#xff1a;通道数量选择&#xff08;根据使用情况而定&#xff09; 硬…

Swift爬虫程序

以下是一个简单的Swift爬虫程序&#xff0c;用于从前程无忧深圳地区招聘财务、会计的数据爬取数据&#xff1a; import Foundation import SwiftSoup// 创建一个请求对象&#xff0c;指定代理信息 var request URLRequest(url: URL(string: "https://www.51job.com/zh/c…