当前位置: 首页 > news >正文

【每日一题】ABC311G - One More Grid Task | 单调栈 | 简单

题目内容

原题链接

给定一个 n n n m m m 列的矩阵,问权值最大的子矩阵的权值是多少。

对于一个矩阵,其权值定义为矩阵中的最小值 m i n v minv minv 乘上矩阵中所有元素的和。

数据范围

  • 1 ≤ n , m ≤ 300 1\leq n,m \leq 300 1n,m300
  • 1 ≤ a i ≤ 300 1\leq a_i\leq 300 1ai300

题解

对于这类矩阵问题,通常做法都是枚举矩阵的下边界和下边界,这样就可以将矩阵看成一个一维数组问题。

考虑对于一个一维数组,找到其中一个子数组(连续子序列),满足子数组的最小值乘上子数组的元素和最大。

那么问题就非常显然了,考虑数组中每个元素作为子数组的最小值,考虑这个子数组的左右端点,就是考虑其左边和右边第一个小于其的元素即可。这个就是单调栈的经典应用,单调栈在这里是 O ( m ) O(m) O(m) 的。

时间复杂度: O ( n 2 m ) O(n^2m) O(n2m)

代码

#include <bits/stdc++.h>
using namespace std;const int N = 310;
int a[N][N];
// 列前缀和
int col[N][N];
int stk[N];
// up ~ down 这个上下界内每个列左边第一个小于该列最小值的列
int L[N], R;
// up ~ down 这个上下界内每个列的元素之和 的前缀和
int pre[N];
// up ~ down 这个上下界内每个列的最小值
int cmin[N];// up ~ down 内一个列的元素和
int up, down;
int v(int idx) {return col[down][idx] - col[up - 1][idx];
}int main()
{int n, m;cin >> n >> m;for (int i = 1; i <= n; ++i)for (int j = 1; j <= m; ++j) {cin >> a[i][j];// 每一行的前缀和col[i][j] = col[i - 1][j] + a[i][j];}long long ans = 0;// 枚举子矩阵的上下边界for (up = 1; up <= n; ++up) {for (int j = 1; j <= m; ++j) cmin[j] = a[up][j];for (down = up; down <= n; ++down) {// 每一列的最小值for (int j = 1; j <= m; ++j) cmin[j] = min(cmin[j], a[down][j]);int top = 0;for (int j = 1; j <= m; ++j) {while (top > 0 && cmin[stk[top]] >= cmin[j]) top -= 1;if (top == 0) L[j] = 1;else L[j] = stk[top] + 1;stk[++top] = j;// 每一行的前缀和pre[j] = pre[j - 1] + v(j);}top = 0;for (int j = m; j >= 1; --j) {while (top > 0 && cmin[stk[top]] > cmin[j]) top -= 1;if (top == 0) R = m;else R = stk[top] - 1;stk[++top] = j;ans = max(ans, 1ll * (pre[R] - pre[L[j] - 1]) * cmin[j]);}}}cout << ans << "\n";return 0;
}
http://www.lryc.cn/news/193457.html

相关文章:

  • 第五十六章 学习常用技能 - 执行 SQL 查询
  • 2023年起重信号司索工(建筑特殊工种)证考试题库及起重信号司索工(建筑特殊工种)试题解析
  • 《华为战略管理法:DSTE实战体系》作者谢宁老师受邀为某电力上市集团提供两天的《成功的产品管理及产品经理》内训。
  • finalshell连接虚拟机中的ubuntu
  • django系列之事务操作
  • stm32学习笔记:中断的应用:对射式红外传感器计次旋转编码器计次
  • one-hot是什么
  • 基于阿基米德优化优化的BP神经网络(分类应用) - 附代码
  • ubuntu20.04配置阿里的kubernetes源
  • 【运维】一些团队开发相关的软件安装。
  • 互联网Java工程师面试题·Java 并发编程篇·第七弹
  • SQL语句常见分类
  • SpringBoot通过配置切换注册中心(多注册中心nacos和eureka)
  • 自动驾驶学习笔记(三)——场景设计
  • 第 115 场 LeetCode 双周赛题解
  • 【IDE插件教学】华为云应用中间件系列—Redis实现(电商游戏应用)排行榜示例
  • Linux:mongodb数据库源码包安装(4.4.25版本)
  • pdf怎么合并在一起?
  • 杀死僵尸进程ZooKeeperMain
  • JavaScript class和function的区别
  • MySQL8.0修改mysql允许远程连接
  • 【算法训练-排序算法 二】【手撕排序】快速排序、堆排序、归并排序
  • C# RestoreFormer 图像修复
  • yolov5+车辆重识别【附代码】
  • C语言练习百题之#ifdef和#ifndef的应用
  • 与C语言不同的基础语法
  • Python文件读写实战:处理日常任务的终极工具!
  • 思维模型 秩序
  • pyqt5移动鼠标时显示鼠标坐标
  • 分享一下开发回收废品小程序的步骤